eslint vscode

2023-05-17 22:52

{
  "window.zoomLevel": 0, // 窗口大小比例
  "workbench.colorTheme": "Default Dark+",
  "diffEditor.wordWrap": "on",
  "editor.wordWrap": "on",
  "editor.fontSize": 14,
  "editor.tabSize": 2,
  "editor.formatOnSave": true, // eslint保存格式化
  "eslint.enable": true,
  "eslint.run": "onType",
  "eslint.options": {
    "extensions": [
      ".js",
      ".vue",
      ".jsx",
      ".tsx"
    ]
  },
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "tabnine.experimentalAutoImports": true,
  "editor.minimap.autohide": true,
  "eslint.codeActionsOnSave.rules": null,
  "editor.detectIndentation": false,
  "settingsSync.ignoredExtensions": []
}

ES2015

2023-05-15 21:37

ES2015+ 备忘清单

快速浏览 ES2015、ES2016、ES2017、ES2018 及以后的 JavaScript 新特性

常用

块范围

<!--rehype:wrap-class=row-span-2-->

Let

function fn () {
  let x = 0
  if (true) {
    let x = 1 // 只在这个`if`里面
  }
}

Const

const a = 1

let 是新的 var。 常量(const) 就像 let 一样工作,但不能重新分配。 请参阅:Let 和 const

反引号字符串

<!--rehype:wrap-class=row-span-2-->

插值

const message = `Hello ${name}`

多行字符串

const str = `
hello
world
`

模板和多行字符串。 请参阅:模板字符串

二进制和八进制文字

let bin = 0b1010010
let oct = 0o755

请参阅:二进制和八进制文字

指数运算符

const byte = 2 ** 8
// 同: Math.pow(2, 8)

新方法

新的字符串方法

"hello".repeat(3)
"hello".includes("ll")
"hello".startsWith("he")
"hello".padStart(8) // "   hello"
"hello".padEnd(8) // "hello   " 
"hello".padEnd(8, '!') // hello!!!
"\u1E9B\u0323".normalize("NFC")

新的数字方法

Number.EPSILON
Number.isInteger(Infinity) // false
Number.isNaN("NaN") // false

新的 Math 方法

Math.acosh(3) // 1.762747174039086
Math.hypot(3, 4) // 5
Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2

新的 Array 方法

// 返回一个真实的数组
Array.from(document.querySelectorAll("*"))
// 类似于 new Array(...),但没有特殊的单参数行为
Array.of(1, 2, 3)

请参阅: 新方法

class Circle extends Shape {

构造函数

  constructor (radius) {
    this.radius = radius
  }

方法

  getArea () {
    return Math.PI * 2 * this.radius
  }

调用超类方法

  expand (n) {
    return super.expand(n) * Math.PI
  }

静态方法

  static createFromDiameter(diameter) {
    return new Circle(diameter / 2)
  }
}

原型的语法糖。 请参阅:

私有类

javascript 默认字段是公共的(public),如果需要注明私有,可以使用(#

class Dog {
  #name;
  constructor(name) {
    this.#name = name;
  }
  printName() {
    //只能在类内部调用私有字段
    console.log(`你的名字是${this.#name}`)
  }
}

const dog = new Dog("putty")
//console.log(this.#name) 
//Private identifiers are not allowed outside class bodies.
dog.printName()

静态私有类

class ClassWithPrivate {
  static #privateStaticField;
  static #privateStaticFieldWithInitializer = 42;

  static #privateStaticMethod() {
    // …
  }
}

Promises

做出承诺

new Promise((resolve, reject) => {
  if (ok) { resolve(result) }
  else { reject(error) }
})

用于异步编程。 请参阅:Promises

使用 Promises

promise
  .then((result) => { ··· })
  .catch((error) => { ··· })

在 finally 中使用 Promise

promise
  .then((result) => { ··· })
  .catch((error) => { ··· })
  .finally(() => {
    /* 独立于成功/错误的逻辑 */
  })

当承诺被履行或被拒绝时,处理程序被调用

Promise 函数

Promise.all(···)
Promise.race(···)
Promise.reject(···)
Promise.resolve(···)

Async-await

async function run () {
  const user = await getUser()
  const tweets = await getTweets(user)
  return [user, tweets]
}

async 函数是使用函数的另一种方式。 请参阅:异步函数

解构 Destructuring

解构赋值

Arrays

const [first, last] = ['Nikola', 'Tesla']

Objects

let {title, author} = {
  title: 'The Silkworm',
  author: 'R. Galbraith'
}

支持匹配数组和对象。 请参阅:解构

默认值

const scores = [22, 33]
const [math = 50, sci = 50, arts = 50] = scores

// Result:
// math === 22, sci === 33, arts === 50

可以在解构数组或对象时分配默认值

函数参数

function greet({ name, greeting }) {
  console.log(`${greeting}, ${name}!`)
}

greet({ name: 'Larry', greeting: 'Ahoy' })

对象和数组的解构也可以在函数参数中完成

默认值

function greet({ name = 'Rauno' } = {}) {
  console.log(`Hi ${name}!`);
}

greet() // Hi Rauno!
greet({ name: 'Larry' }) // Hi Larry!

重新分配键

function printCoordinates({ left: x, top: y }) {
  console.log(`x: ${x}, y: ${y}`)
}

printCoordinates({ left: 25, top: 90 })

此示例将 x 分配给 left 键的值

循环

for (let {title, artist} of songs) {
  ···
}

赋值表达式也在循环中工作

对象解构

const { id, ...detail } = song;

使用 rest(...) 运算符单独提取一些键和对象中的剩余键

扩展运算符 Spread

对象扩展

与对象扩展

const options = {
  ...defaults,
  visible: true
}

没有对象扩展

const options = Object.assign(
  {}, defaults,
  { visible: true })

对象扩展运算符允许您从其他对象构建新对象。 请参阅:对象传播

数组扩展

具有数组扩展

const users = [
  ...admins,
  ...editors,
  'rstacruz'
]

没有数组扩展

const users = admins
  .concat(editors)
  .concat([ 'rstacruz' ])

扩展运算符允许您以相同的方式构建新数组。 请参阅:扩展运算符

函数 Functions

函数参数

<!--rehype:wrap-class=row-span-3-->

默认参数

function greet (name = 'Jerry') {
  return `Hello ${name}`
}

Rest 参数

function fn(x, ...y) {
  // y 是一个数组
  return x * y.length
}

扩展

fn(...[1, 2, 3])
// 与 fn(1, 2, 3) 相同

Default(默认), rest, spread(扩展)。 请参阅:函数参数

箭头函数

<!--rehype:wrap-class=row-span-3-->

箭头函数

setTimeout(() => {
  ···
})

带参数

readFile('text.txt', (err, data) => {
  ...
})

隐式返回

arr.map(n => n*2)
// 没有花括号 = 隐式返回
// 同: arr.map(function (n) { return n*2 })
arr.map(n => ({
  result: n*2
}))
// 隐式返回对象需要在对象周围加上括号

类似函数,但保留了 this。 请参阅:箭头函数

参数设置默认值

function log(x, y = 'World') {
  console.log(x, y);
}

log('Hello')          // Hello World
log('Hello', 'China') // Hello China
log('Hello', '')      // Hello

与解构赋值默认值结合使用

function foo({x, y = 5} = {}) {
  console.log(x, y);
}

foo() // undefined 5

name 属性

function foo() {}
foo.name // "foo"

length 属性

function foo(a, b){}
foo.length // 2

Objects

速记语法

module.exports = { hello, bye }

同下:

module.exports = {
  hello: hello, bye: bye
}

请参阅:对象字面量增强

方法

const App = {
  start () {
    console.log('running')
  }
}
// 同: App = { start: function () {···} }

请参阅:对象文字增强

Getters and setters

const App = {
  get closed () {
    return this.status === 'closed'
  },
  set closed (value) {
    this.status = value ? 'closed' : 'open'
  }
}

请参阅:对象字面量增强

计算属性名称

let event = 'click'
let handlers = {
  [`on${event}`]: true
}
// 同: handlers = { 'onclick': true }

请参阅:对象字面量增强

提取值

const fatherJS = { age: 57, name: "张三" }
Object.values(fatherJS)
// [57, "张三"]
Object.entries(fatherJS)
// [["age", 57], ["name", "张三"]]

Modules 模块

Imports 导入

import 'helpers'
// 又名: require('···')

import Express from 'express'
// 又名: const Express = require('···').default || require('···')

import { indent } from 'helpers'
// 又名: const indent = require('···').indent

import * as Helpers from 'helpers'
// 又名: const Helpers = require('···')

import { indentSpaces as indent } from 'helpers'
// 又名: const indent = require('···').indentSpaces

import 是新的 require()。 请参阅:Module imports

Exports 导出

export default function () { ··· }
// 又名: module.exports.default = ···

export function mymethod () { ··· }
// 又名: module.exports.mymethod = ···

export const pi = 3.14159
// 又名: module.exports.pi = ···

const firstName = 'Michael';
const lastName = 'Jackson';
const year = 1958;
export { firstName, lastName, year };

export * from "lib/math";

export 是新的module.exports。 请参阅:Module exports

as 关键字重命名

import {
  lastName as surname // 导入重命名
} from './profile.js';

function v1() { ... }
function v2() { ... }

export { v1 as default };
// 等同于 export default v1;

export {
  v1 as streamV1,           // 导出重命名
  v2 as streamV2,           // 导出重命名
  v2 as streamLatestVersion // 导出重命名
};

动态加载模块

button.addEventListener('click', event => {
  import('./dialogBox.js')
    .then(dialogBox => {
      dialogBox.open();
    })
    .catch(error => {
      /* Error handling */
    })
});

ES2020提案 引入 import() 函数

import() 允许模块路径动态生成

const main = document.querySelector('main')

import(`./modules/${someVariable}.js`)
  .then(module => {
    module.loadPageInto(main);
  })
  .catch(err => {
    main.textContent = err.message;
  });

import.meta

ES2020import 命令添加了一个元属性 import.meta,返回当前模块的元信息

new URL('data.txt', import.meta.url)

Node.js 环境中,import.meta.url返回的总是本地路径,即 file:URL 协议的字符串,比如 file:///home/user/foo.js

导入断言(Import Assertions)

<!--rehype:wrap-class=col-span-2-->

静态导入

import json from "./package.json" assert {type: "json"}
// 导入 json 文件中的所有对象

动态导入

const json = 
     await import("./package.json", { assert: { type: "json" } })

Generators

Generator 函数

function* idMaker () {
  let id = 0
  while (true) { yield id++ }
}

let gen = idMaker()
gen.next().value  // → 0
gen.next().value  // → 1
gen.next().value  // → 2

情况很复杂。 请参阅:Generators

For..of + 迭代器(iterator)

<!--rehype:wrap-class=row-span-2-->
let fibonacci = {
  [Symbol.iterator]() {
    let pre = 0, cur = 1;
    return {
      next() {
        [pre, cur] = [cur, pre + cur];
        return { done: false, value: cur }
      }
    }
  }
}

for (var n of fibonacci) {
  // 在 1000 处截断序列
  if (n > 1000) break;
  console.log(n);
}

用于迭代生成器和数组。 请参阅:For..of iteration

与 Iterator 接口的关系

var gen = {};
gen[Symbol.iterator] = function* () {
  yield 1;
  yield 2;
  yield 3;
};

[...gen] // => [1, 2, 3]

Generator 函数赋值给 Symbol.iterator 属性,从而使得 gen 对象具有了 Iterator 接口,可以被 ... 运算符遍历了

Symbol.iterator 属性

function* gen() { /* some code */ }
var g = gen();

g[Symbol.iterator]() === g // true

gen 是一个 Generator 函数,调用它会生成一个遍历器对象g。它的 Symbol.iterator 属性,也是一个遍历器对象生成函数,执行后返回它自己

另见

git 备忘记清单

2023-05-15 21:33

Git 备忘清单

入门

创建存储库

创建一个新的本地存储库

$ git init [项目名称]

克隆存储库(代码仓库)

$ git clone <git_url>

将存储库克隆到指定目录

$ git clone <git_url> 指定目录

将存储库克隆到指定目录,并指定分支

$ git clone <git_url> -b <分支名称> 指定目录

做出改变

<!--rehype:wrap-class=row-span-3-->

在工作目录中显示修改后的文件,为您的下一次提交暂存

$ git status

暂存文件,准备提交

$ git add [file]

暂存所有更改的文件,准备提交

$ git add .

将所有暂存文件提交到版本化历史记录

$ git commit -m "commit message"

将所有跟踪的文件提交到版本化历史记录

$ git commit -am "commit message"

取消暂存文件,保留文件更改

$ git reset [file]

将所有内容恢复到最后一次提交

$ git reset --hard

已更改但未暂存内容的差异

$ git diff

已 commited 但尚未提交的内容的差异

$ git diff --staged

在指定分支之前应用当前分支的任何提交

$ git rebase [branch]

配置

<!--rehype:wrap-class=row-span-2-->

设置将附加到您的提交和标签的名称

$ git config --global user.name "name"

设置将附加到您的提交和标签 tags 的电子邮件地址

$ git config --global user.email "email"

启用 Git 输出的一些着色

$ git config --global color.ui auto

在文本编辑器中编辑全局配置文件

$ git config --global --edit

显示本地 repo 配置设置

$ git config --list

删除全局设置

$ git config --global --unset <entry-name>

使用分支

<!--rehype:wrap-class=row-span-3-->

列出所有本地分支

$ git branch

列出所有分支,本地和远程

$ git branch -av

切换到 my_branch,并更新工作目录

$ git checkout my_branch

创建一个名为 new_branch 的新分支

$ git checkout -b new_branch

删除名为 my_branch 的分支

$ git branch -d my_branch

将分支 A 合并到分支 B

$ git checkout branchB
$ git merge branchA

标记当前提交

$ git tag my_tag

从远程分支中创建并切换到本地分支

$ git checkout -b <branch-name> origin/<branch-name>
<!--rehype:className=wrap-text-->

临时提交

# 保存已修改和分阶段的更改
$ git stash
# 列出隐藏文件更改的堆栈顺序
$ git stash list
# 从存储堆栈顶部编写工作
$ git stash pop
# 丢弃存储堆栈顶部的更改
$ git stash drop
# 回到某个 stash 的状态
$ git stash apply <stash@{n}>
# 删除所有的 stash
$ git stash clear

观察你的存储库

<!--rehype:wrap-class=row-span-2-->

显示当前活动分支的提交历史

$ git log

显示 branchA 上不在 branchB 上的提交

$ git log branchB..branchA

显示更改文件的提交,即使跨重命名

$ git log --follow [file]

显示 branchA 中的内容与 branchB 中的内容的差异

$ git diff branchB...branchA

以人类可读的格式显示 Git 中的任何对象

$ git show [SHA]

忽略文件 .gitignore

<!--rehype:wrap-class=row-span-4-->

文件 .gitignore 指定了 Git 应该忽略的 未跟踪的 文件

:- | :- :- | :- 行首 # | 全行注释,不支持行尾类注释 (转义 \#) 行首 ! | 否定模式 (转义 \!) ** | 匹配任意路径 * | 匹配任意多个字符 ? | 匹配任意一个字符 doc/** | 匹配 doc 文件夹下的全部内容 doc/**/a | 匹配任意深度路径下的 a 文件或文件夹 / | 表示路径分隔符,不区分操作系统 / 结尾 | 仅会匹配文件夹,否则会匹配文件和文件夹 空行 | 不匹配任何文件 行尾空格 | 默认被忽略,可使用\进行转义 行首空格 | 被正常处理,不会被忽略

当前 .gitignore 文件定义规则的优先级高于上级路径 .gitignore 定义规则的优先级;后定义的规则优先级高于前面定义规则的优先级

# 忽略当前目录logs文件夹下的全部内容
/logs/
/logs/*
/logs/**
# 上述几条规则等效

# 忽略 Mac 系统文件,包括任意子路径下的同名文件(夹)
.DS_store

# 忽略 node_modules 文件夹,包括任意子路径下的同名文件夹
node_modules/

# 忽略任意子路径下build、target文件夹,
# 但不忽略src/main、src/test下的build、target文件夹
build/
!**/src/main/**/build/
!**/src/test/**/build/
target/
!**/src/main/**/target/
!**/src/test/**/target/

# 使用 ! 重新包含指定文件(夹)
!logs/.gitkeep
<!--rehype:className=wrap-text-->

重构文件名

# 从工作目录中删除文件并暂存删除
git rm <filename>

# 从版本控制中删除文件但在本地保留文件
git rm --cached <filename>

# 更改文件名并准备提交
git mv <filename-orig> <filename-renamed>

同步

<!--rehype:wrap-class=row-span-2-->

从该 Git 远程获取所有分支

$ git fetch [alias]

将远程分支合并到当前分支以使其保持最新状态

$ git merge [alias]/[branch]
# 没有快进
$ git merge --no-ff [alias]/[branch]
# 仅快进
$ git merge --ff-only [alias]/[branch]

将本地分支提交传输到远程存储库分支

$ git push [alias] [branch]

从跟踪远程分支获取并合并任何提交

$ git pull

将另一个分支的一个特定提交合并到当前分支

$ git cherry-pick [commit_id]

远程

<!--rehype:wrap-class=row-span-2-->

添加一个 git URL 作为别名

$ git remote add [alias] [url]

显示您设置的远程存储库的名称

$ git remote

显示远程存储库的名称和 URL

$ git remote -v

删除远程存储库

$ git remote rm [remote repo name]

更改 git repo 的 URL

$ git remote set-url origin [git_url]

跟踪路径更改

从项目中删除文件并暂存删除以进行提交

$ git rm [file]

更改现有文件路径并暂存移动

$ git mv [existing-path] [new-path]

显示所有提交日志,并指示任何移动的路径

$ git log --stat -M

git 配置 ssh 代理

<!--rehype:wrap-class=col-span-2-->
$ cat ~/.ssh/config
Host gitlab.com
# 直接使用 sh**socks 提供的 socks5 代理端口
ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p 

Host github.com
ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p    
<!--rehype:className=wrap-text-->

.gitattributes

# 设置默认行为,以防人们没有设置 core.autocrlf
* text=auto
# 明确声明您希望始终规范化并在结帐时
# 转换为本机行结尾的文本文件
*.c text
*.h text
# 声明在结帐时始终以 CRLF 行结尾的文件
*.sln text eol=crlf
# 表示所有真正二进制且不应修改的文件
*.png binary
*.jpg binary
# 标记或取消标记要根据存储库的语言统计数据而
# 忽略或默认隐藏差异的路径
search/index.json linguist-generated=true
# 以下属性统计 SQL 文件
*.sql linguist-detectable=true
# 从统计信息中排除
docs/formatter.rb linguist-documentation=false
# 将它们从统计信息中排除
special-vendored-path/* linguist-vendored
# 将所有 .rb 文件检测为 Java 文件
*.rb linguist-language=Java

Git 技巧

重命名分支

  • 重命名new

    $ git branch -m <new>
    $ git branch -m <old> <new> #重命名分支  
    
  • 推送并重置

    $ git push origin -u <new>
    
  • 删除远程分支

    $ git push origin --delete <old> #方法1
    $ git push origin :oldBranchName #方法2
    
<!--rehype:className=style-timeline-->

Log

按内容搜索更改

$ git log -S ' term in the source'

显示特定文件随时间的变化

$ git log -p <file_name>

打印出很酷的日志可视化

$ git log --pretty=oneline --graph --decorate --all
<!--rehype:className=wrap-text-->

分支

<!--rehype:wrap-class=row-span-2-->

列出所有分支及其上游

$ git branch -vv 

快速切换到上一个分支

$ git checkout -

只获取所有远程分支

$ git branch -r

从另一个分支签出单个文件

$ git checkout <branch> -- <file>

删除本地存在远程不存在的分支

git remote prune origin

Commit

$ git commit -v --amend

重写最后的提交信息

忽略文件的权限变化

git config core.fileMode false

不再将文件的权限变化视作改动

Git 别名

$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status

设置大小写敏感

# 查看git 的设置
$ git config --get core.ignorecase
# 设置大小写敏感
$ git config core.ignorecase false
# 远程有俩相同目录,通过这种方式清除掉,然后提交记录
$ git rm -r --cached <目录/文件> 

修改远程 Commit 记录

<!--rehype:wrap-class=row-span-4-->
$ git rebase -i HEAD~3
# 表示要修改当前版本的倒数第三次状态
# 将要更改的记录行首单词 pick 改为 edit
pick 96dc3f9 提交 commit 描述内容 1
pick f1cce8a 提交 commit 描述内容 2
pick 6293516 提交 commit 描述内容 3
# Rebase eeb03a4..6293516 onto eeb03a4 
#                     (3 commands)
#
# Commands:
# p, pick = 使用提交
# r, reword = 使用提交,但编辑提交消息
# e, edit = 使用提交,但停止修改
# s, squash = 使用提交,但融合到先前的提交中
# f, fixup = 像 squash,但丢弃此提交的日志消息
# x, exec = 使用 shell 运行命令(该行的其余部分)
# d, drop = 删除提交

保存并退出,会弹出下面提示

# 您现在可以修改提交,使用
# 
#   git commit --amend
# 
# 对更改感到满意后,运行
# 
#   git rebase --continue
#
# 1. 通过这条命令进入编辑更改 commit,保存退出
$ git commit --amend
# 2. 保存退出确认修改,继续执行下面命令, 
$ git rebase --continue
# 如果修改多条记录反复执行上面两条命令直到完成所有修改

# 最后,确保没有人提交进行推送,最好不要加 -f 强制推送
$ git push -f origin master

撤销远程记录

# 撤销一条记录   
$ git reset --hard HEAD~1
# 强制同步到远程仓库  
$ git push -f origin HEAD:master

放弃本地修改内容

# 如果有的修改以及加入暂存区的话
$ git reset --hard 
# 还原所有修改,不会删除新增的文件
$ git checkout . 
# 下面命令会删除新增的文件
$ git clean -xdf

获取最近一次提交的 Hash

$ git rev-parse HEAD # e10721cb8859b2c
# 获取短 hash
$ git rev-parse --short HEAD # e10721c

删除已经合并到 master 的分支

$ git branch --merged master | grep -v '^\*\|  master' | xargs -n 1 git branch -d
<!--rehype:className=wrap-text-->

把 A 分支的某一个 commit,放到 B 分支上

# 切换到 B 分支
$ git checkout <B>
# 将 A 分支 <hash-id> 的内容 pick 到 B 分支
$ git cherry-pick <hash-id>

回到远程仓库的状态

$ git fetch --all && git reset --hard origin/master
<!--rehype:className=wrap-text-->

抛弃本地所有的修改,回到远程仓库的状态

重设第一个 commit

$ git update-ref -d HEAD

把所有的改动都重新放回工作区,并清空所有的 commit,这样就可以重新提交第一个 commit

查看冲突文件列表

$ git diff --name-only --diff-filter=U

展示工作区的冲突文件列表

<!--rehype:wrap-class=row-span-2-->

输出工作区和暂存区的 different (不同)。

$ git diff

还可以展示本地仓库中任意两个 commit 之间的文件变动:

$ git diff <commit-id> <commit-id>

展示暂存区和最近版本的不同

git diff --cached

中文乱码的解决方案

$ git config --global core.quotepath false

展示暂存区、工作区和最近版本的不同

$ git diff HEAD

输出工作区、暂存区 和本地最近的版本(commit)的different(不同)。

删除已经合并到 master 的分支

$ git branch --merged master | grep -v '^\*\|  master' | xargs -n 1 git branch -d
<!--rehype:className=wrap-text-->

关联远程分支

<!--rehype:wrap-class=row-span-2-->
$ git branch -u origin/mybranch

或者在 push 时加上 -u 参数

git push origin/mybranch -u

关联之后,git branch -vv 就可以展示关联的远程分支名了, 同时推送到远程仓库直接:git push,不需要指定远程仓库

查看远程分支和本地分支的对应关系

$ git remote show origin

展示当前分支的最近的 tag

$ git describe --tags --abbrev=0

查看某段代码是谁写的

$ git blame <file-name>

blame 的意思为责怪,你懂的。

修改作者名

$ git commit --amend --author='Author Name <email@address.com>'
<!--rehype:className=wrap-text-->

修改远程仓库的 url

$ git remote set-url origin <URL>

增加远程仓库

$ git remote add origin <remote-url>
<!--rehype:className=wrap-text-->

列出所有远程仓库

$ git remote -v

查看两个星期内的改动

$ git whatchanged --since='2 weeks ago'

从 stash 中拿出某个文件的修改

$ git checkout <stash@{n}> -- <file-path>
<!--rehype:className=wrap-text-->

展示所有 tracked 的文件

$ git ls-files -t

展示所有 untracked 的文件

$ git ls-files --others

展示所有忽略的文件

$ git ls-files --others -i --exclude-standard
<!--rehype:className=wrap-text-->

把某一个分支导出成一个文件

$ git bundle create <file> <branch-name>

从包中导入分支

<!--rehype:wrap-class=row-span-2-->
$ git clone repo.bundle <repo-dir> -b <branch-name>
<!--rehype:className=wrap-text-->

新建一个分支,分支内容就是上面 git bundle create 命令导出的内容

执行 rebase 之前自动 stash

$ git rebase --autostash

从远程仓库根据 ID,拉下某一状态,到本地分支

$ git fetch origin pull/<id>/head:<branch-name>
<!--rehype:className=wrap-text-->

详细展示一行中的修改

$ git diff --word-diff

清除 gitignore 文件中记录的文件

$ git clean -X -f

展示忽略的文件

$ git status --ignored

commit 历史中显示 Branch1 有的但是 Branch2 没有 commit

$ git log Branch1 ^Branch2

在 commit log 中显示 GPG 签名

$ git log --show-signature

新建并切换到新分支上,同时这个分支没有任何 commit

$ git checkout --orphan <branch-name>

相当于保存修改,但是重写 commit 历史

展示任意分支某一文件的内容

$ git show <branch-name>:<file-name>

配置 http 和 socks 代理

<!--rehype:wrap-class=row-span-4-->
# 查看代理
$ git config --global http.proxy
$ git config --global https.proxy
$ git config --global socks.proxy

# 设置代理
# 适用于 privoxy 将 socks 协议转为 http 协议的 http 端口
$ git config --global http.proxy http://127.0.0.1:1080
$ git config --global https.proxy http://127.0.0.1:1080
$ git config --global socks.proxy 127.0.0.1:1080

# 取消代理
$ git config --global --unset http.proxy
$ git config --global --unset https.proxy
$ git config --global --unset socks.proxy

# 只对 github.com 设置代理
$ git config --global http.https://github.com.proxy socks5://127.0.0.1:1080
$ git config --global https.https://github.com.proxy socks5://127.0.0.1:1080

# 取消 github.com 代理
$ git config --global --unset http.https://github.com.proxy
$ git config --global --unset https.https://github.com.proxy

clone 最新一次提交

$ git clone --depth=1 https://github.com/user/repo.git

只会 clone 最近一次提交,将减少 clone 时间

忽略某个文件的改动

<!--rehype:wrap-class=row-span-2-->

关闭 track 指定文件的改动,也就是 Git 将不会在记录这个文件的改动

git update-index --assume-unchanged path/to/file
<!--rehype:className=wrap-text-->

恢复 track 指定文件的改动

git update-index --no-assume-unchanged path/to/file
<!--rehype:className=wrap-text-->

以最后提交的顺序列出所有 Git 分支

git for-each-ref --sort=-committerdate --format='%(refname:short)' refs/heads

最新的放在最上面

在 commit log 中查找相关内容

git log --all --grep='<given-text>'

通过 grep 查找,given-text: 所需要查找的字段

把暂存区的指定 file 放到工作区中

git reset <file-name>

不添加参数,默认是 -mixed

配置 SSH 协议代理

# 对于使用 git@ 协议的,可以配置 socks5 代理
# macOS 系统编辑 ~/.ssh/config 文件,添加这几行,设置 github 代理
Host github.com
  ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p
<!--rehype:className=wrap-text-->

git 代码统计

查看 git 上的个人代码量

  • username 需要改成自己的
git log --author="username" --pretty=tformat: --numstat | awk \
'{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -

统计每个人增删行数

git log --format='%aN' | sort -u |\
  while read name; do echo -en "$name\t";\
  git log --author="$name" --pretty=tformat: --numstat | awk \
  '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s, removed lines: %s, total lines: %s\n", add, subs, loc }' -; done

查看仓库提交者排名

这里是排名前十,也可以更改排名

git log --pretty='%aN' | sort | uniq -c | sort -k1 -n -r | head -n 10

提交数统计

git log --oneline | wc -l

Conventional Commmits

格式

<!--rehype:wrap-class=col-span-3-->
<type>(<scope>): <short summary>
  │       │             │
  │       │             └─⫸ 紧凑简短的描述,无需大写,也不需要用句号结尾
  │       │
  │       └─⫸ Commit 范围: animations|bazel|benchpress|common|compiler|compiler-cli|core|
  │                          elements|forms|http|language-service|localize|platform-browser|
  │                          platform-browser-dynamic|platform-server|router|service-worker|
  │                          upgrade|zone.js|packaging|changelog|docs-infra|migrations|ngcc|ve|
  │                          devtools....
  │
  └─⫸ Commit 类型: build|ci|doc|docs|feat|fix|perf|refactor|test
                    website|chore|style|type|revert

常用

<!--rehype:wrap-class=row-span-1-->

| 类型 | 描述 | | ----------|------------ | | feat: | 新特性 | | fix(scope): | 修复 scope 中的 Bug | | feat!: / feat(scope)!: | breaking change / 重构 API | | chore(deps): | 更新依赖 |

<!--rehype:className=left-align-->

Commit 类型

<!--rehype:wrap-class=col-span-2-->

| 类型 | 描述 | | ----------|------------ | | build: | 变更影响的是构建系统或者外部依赖 (如: gulp, npm) | | ci: | 修改了 CI 配置文件或脚本 (如: Github Action, Travis) | | chore: | 【重要】 变更不影响源代码或测试(如更新了辅助工具、库等) | | docs: | 只修改了文档 | | feat: | 【重要】 一个新特性 | | fix: | 【重要】 修复了一个 Bug | | perf: | 增强性能的代码变更 | | refactor: | 并非修复 Bug 或添加新特性的代码变更 | | revert: | 回退代码 | | style: | 变更不影响一些有意义的代码 (如: 删除空格、格式化代码、添加分号等) | | test: | 添加测试代码或修正已有的测试 |

<!--rehype:className=left-align-->

HOC

2023-05-15 06:54

import React, { useReducer, useContext } from 'react';

// 创建一个 Context
const MyContext = React.createContext({});

// 定义一个 reducer
const reducer = (state:any, action:any) => {
    switch (action.type) {
        case 'INCREMENT':
            return { count: state.count + action.payload };
        case 'DECREMENT':
            return { count: state.count - action.payload };
        default:
            return state;
    }
};

// 定义一个 HOC
function withCounter<T>(WrappedComponent:any)  {
    // 返回一个新组件
    const NewComponent = (props:T) => {
        // 使用 useReducer 定义状态和更新函数
        const [state, dispatch] = useReducer(reducer, { count: 0 });

        // 将状态和更新函数通过 Context 共享给子组件
        return (
            <MyContext.Provider value={{ state, dispatch }}>
                <WrappedComponent {...props} />
            </MyContext.Provider>
        );
    };

    return NewComponent;
};

export { withCounter, MyContext };
import React, { useContext } from 'react';
import { withCounter, MyContext } from './withCounter';

const Counter = () => {
    // 从 Context 中获取状态和更新函数
    const { state , dispatch } = useContext(MyContext);
    // console.log(state);
    return (
        <>
            <div>Count: {state?.count}</div>
            <button onClick={() => dispatch({ type: 'INCREMENT', payload: 1 })}>
                Increment
            </button>
            <button onClick={() => dispatch({ type: 'DECREMENT', payload: 1 })}>
                Decrement
            </button>
        </>
    );
};

// 使用 withCounter 包装 Counter 组件
export default withCounter(Counter);

recursion get object property

2023-04-06 08:22

// Define a function to recursively get object properties
function getObjectProperty(obj, prop) {
  // Split the property string into an array of nested properties
  const props = prop.split('.');
  // Get the first property in the array
  const firstProp = props.shift();
  // Get the value of the first property
  const value = obj[firstProp];
  // If there are no more nested properties, return the value
  if (props.length === 0) {
    return value;
  }
  // If the value is an object, recursively call the function with the remaining properties
  if (typeof value === 'object' && value !== null) {
    return getObjectProperty(value, props.join('.'));
  }
  // If the value is not an object or null, return undefined
  return undefined;
}

// Call the function with an object and a property string to get the value of the property
const obj = { a: { b: { c: 'value' } } };
const prop = 'a.b.c';
const value = getObjectProperty(obj, prop);
console.log(value); // Output: 'value'

single

2023-04-06 08:17

class Single {
  static instance = null;
  data = [];

  constructor() {
    if (!Single.instance) {
      Single.instance = this;
    }
    return Single.instance;
  }

  addData(item) {
    this.data.push(item);
  }

  getData() {
    return this.data;
  }
}

// Usage:
const single1 = new Single();
const single2 = new Single();

console.log(single1 === single2); // true

single1.addData('foo');
single2.addData('bar');

console.log(single1.getData()); // ['foo', 'bar']
console.log(single2.getData()); // ['foo', 'bar']

angular 分页指令

2023-03-28 14:47
import {Directive, HostListener} from '@angular/core';
import {ActivatedRoute} from "@angular/router";
import {UpdateListPageService} from "../services/update-list-page.service";
import {IndexPageComponent} from "../pages/index-page/index-page.component";

@Directive({
  selector: '[appScrollToBottom]'
})
export class ScrollToBottomDirective {

  constructor( private route:ActivatedRoute,
               private getList:UpdateListPageService,
               private indexPageComponent:IndexPageComponent
               ) { }

  @HostListener('window:scroll',['$event'])
  onScroll(event:any){
    let windowHeight = "innerHeight" in window ? window.innerHeight : document.documentElement.offsetHeight;
    let body = document.body, html = document.documentElement;
    let docHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
    let windowBottom = windowHeight + window.pageYOffset;
    const id = Number(this.route.snapshot.queryParamMap.get('id'));
    if (windowBottom >= docHeight) {
      // 已经滚动到底部
      const pageInfo = this.indexPageComponent.pageInfo;
      if(pageInfo.pageIndex !== pageInfo.pageTotal){
        this.getList.getData(id,++pageInfo.pageIndex)
      }
      // console.log('到底了', id,pageInfo, this.indexPageComponent)
    } else {
      // 没有滚动到底部
      // console.log('没到底了', id)
    }
  }
}

给父组件实例useImperativeHandle

2023-03-28 10:05
function FancyInput(props, ref) {
  const inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));
  return <input ref={inputRef} />;
}
FancyInput = forwardRef(FancyInput);


父组件使用

<FancyInput ref={inputRef} />
inputRef.current.focus()

ng加载第三方库

2023-03-28 09:31

加入更多第三方的JavaScript或CSS,例如加入jQuery和bootstrap,可以先使用npm进行下载

npm install --save jquery npm install --save bootstrap

接着调整angular-cli.json里面app.styles和app.scripts设定

"styles": [
  "../node_modules/bootstrap/dist/css/bootstrap.css",
  "styles.css"
],
"scripts": [
  "../node_modules/jquery/dist/jquery.js",
  "../node_modules/bootstrap/dist/js/bootstrap.js"
],

如果 ng serve指令正在执行中的话,要先关掉然后重新执行,才会读到新的angular-cli.json的设定档

接着就可以在画面上自由加入bootstrap的样式

ng http

2023-03-28 09:18
import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http';
import {Observable} from "rxjs";
import {apiListProps, AppList, methodEnum} from "./apiList";

@Injectable({
  providedIn: 'root'
})
export class HttpRequestService {

  constructor(private http: HttpClient) {
  }

  getData(url: string, params?: any, headers?: any): Observable<any> {
    const httpHeaders = new HttpHeaders(headers);
    return this.http.get(url, {params, headers: httpHeaders});
  }

  postData(url: string, data: any, headers?: any): Observable<any> {

    const httpHeaders = new HttpHeaders(headers);
    return this.http.post<any>(url, data, {headers: httpHeaders});
  }


  public fetch(api: apiListProps, data?: any, type?: string): Observable<any> {

    const params: any = new HttpParams({fromObject: data});
    const currentOptions = {
      params: api.method === methodEnum.get ? params : '',
      body: params,
      headers: {
         'Content-type': type === 'form' ? 'application/x-www-form-urlencoded':'application/json',
      }
    }
    return this.http.request(api.method, api.url, currentOptions);
  }

}

angular Util

2023-03-28 09:15
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class UtilService {

  constructor() { }

// 生成指定范围内的随机整数
  getRandomInt(min: number, max: number): number {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  }

// 生成指定长度的不重复随机字符串
  generateUniqueString(length: number): string {
    let result = '';
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    const charactersLength = characters.length;
    for (let i = 0; i < length; i++) {
      result += characters.charAt(Math.floor(Math.random() * charactersLength));
    }
    return result;
  }

    
  // 防抖函数
  debounce(fn: Function, delay: number): Function {
    if (typeof fn !== 'function') {
      throw new TypeError('Expected a function');
    }
    let timer: any = null;
    return function (this:any) {
      const context = this;
      const args = arguments;
      clearTimeout(timer);
      timer = setTimeout(() => {
        fn.apply(context, args);
      }, delay);
    };
  }

  // 节流函数
  throttle(fn: Function, delay: number): Function {
    if (typeof fn !== 'function') {
      throw new TypeError('Expected a function');
    }
    let timer: any = null;
    let startTime = Date.now();
    return function (this:any) {
      const context = this;
      const args = arguments;
      const curTime = Date.now();
      const remaining = delay - (curTime - startTime);
      clearTimeout(timer);
      if (remaining <= 0) {
        fn.apply(context, args);
        startTime = Date.now();
      } else {
        timer = setTimeout(() => {
          fn.apply(context, args);
        }, remaining);
      }
    };
  }
}

nest platform

2023-03-28 09:11
目前 NestJS 支持两个 Node HTTP 平台:Express 和 Fastify。从技术上讲,一旦创建了适配器,Nest 便可以使用任何 Node HTTP 框架

### platform-express

import { NestFactory } from '@nestjs/core'
import { AppModule } from './app.module'
import { NestExpressApplication } from '@nestjs/platform-express'

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule)
  await app.listen(3000)
}
bootstrap()

### platform-fastify

import { NestFactory } from '@nestjs/core'
import { AppModule } from './app.module'
import { NestFastifyApplication } from '@nestjs/platform-fastify'

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(AppModule)
  app.enableCors() // 开启Cors
  app.register(fastifyCsrf)
  await app.listen(4000, '0.0.0.0')
  
  console.log(`Application is running on: ${await app.getUrl()}`)
}
bootstrap()

nest dir

2023-03-28 09:09

├── src      # 源代码目录
│   ├── app.module.ts          # 应用程序的根模块
│   ├── app.controller.spec.ts # 控制器的单元测试
│   ├── app.controller.ts      # 单个路由的基本控制器
│   ├── app.service.ts         # 具有单一方法的基本服务
│   └── main.ts # 应用程序的入口文件
│               # 它使用核心函数 NestFactory 来创建 Nest 应用程序的实例
└── test      # 测试目录
    ├── app.e2e-spec.ts
    └── jest-e2e.json

nestCli

2023-03-28 09:08

NestJS 需要 Node.js >= 12

$ npm i -g @nestjs/cli
$ nest new project-name
Nest CLI 是一个命令行界面工具,可以帮助你初始化、开发和维护你的Nest应用程序,安装依赖并启动开发服务器

$ cd <your-project-name>
$ npm run start
当你准备将应用发布到生产环境时,请运行:

$ npm run build
此命令会在 ./dist 文件夹中为你的应用创建一个生产环境的构建版本

命令	       别名	               描述
new	        n	            使用模板快速创建应用
generate	   g	    自动生成Controller、Providers 和 Modules
build		           打包并输出./dist目录
start		           打包并运行
add		            安装一个符合Nest的库,同npm install
info	       i	 输出系统信息、CLI版本和Nest Package信息

mysql 数据类型

2023-03-28 09:01


CHAR	String (0 - 255)
VARCHAR	String (0 - 255)
TINYTEXT	String (0 - 255)
TEXT	String (0 - 65535)
BLOB	String (0 - 65535)
MEDIUMTEXT	String (0 - 16777215)
MEDIUMBLOB	String (0 - 16777215)
LONGTEXT	String (0 - 429496­7295)
LONGBLOB	String (0 - 429496­7295)
ENUM	One of preset options
SET	Selection of preset options


DATE	yyyy-MM-dd
TIME	hh:mm:ss
DATETIME	yyyy-MM-dd hh:mm:ss
TIMESTAMP	yyyy-MM-dd hh:mm:ss
YEAR	yyyy


TINYINT x	Integer (-128 to 127)
SMALLINT x	Integer (-32768 to 32767)
MEDIUMINT x	Integer (-8388608 to 8388607)
INT x	Integer (-2147­483648 to 214748­3647)
BIGINT x	Integer (-9223­372­036­854­775808 to 922337­203­685­477­5807)
FLOAT	Decimal (precise to 23 digits)
DOUBLE	Decimal (24 to 53 digits)
DECIMAL	"­DOU­BLE­" stored as string

mysql 备份

2023-03-28 08:58

创建备份

mysqldump -u user -p db_name > db.sql
导出不带架构的数据库

mysqldump -u user -p db_name --no-data=true --add-drop-table=false > db.sql
恢复备份

mysql -u user -p db_name < db.sql

mysql 常用

2023-03-28 08:57


数据库 Database
CREATE DATABASE db ;	创建数据库
SHOW DATABASES;	列出数据库
USE db;	切换到数据库
CONNECT db ;	切换到数据库
DROP DATABASE db;	删除数据库
表 Table
SHOW TABLES;	列出当前数据库的表
SHOW FIELDS FROM t;	表的列表字段
DESC t;	显示表格结构
SHOW CREATE TABLEt;	显示创建表sql
TRUNCATE TABLEt;	删除表中的所有数据
DROP TABLEt;	删除表格
Proccess
show processlist;	列出进程
kill pid;	杀死进程

登录mysql

2023-03-28 08:56

# 默认用户名<root>,-p 是密码,
# 参数后面不需要空格
mysql -h 127.0.0.1 -u <用户名> -p<密码>
mysql -D 数据库名 -h 主机名 -u 用户名 -p
mysql -h <host> -P <端口号> -u <user> -p [db_name]
mysql -h <host> -u <user> -p [db_name]

# 显示当前mysql的version的各种信息
mysql> status;
# 显示当前mysql的version信息
mysql> select version(); 
# 查看 MySQL 端口号
mysql> show global variables like 'port';

装饰器和属性

2023-03-28 08:41

可以在类、类方法、访问器、属性和方法参数上使用装饰器。


import { Syncable, triggersSync, preferCache, required } from "mylib"

@Syncable
class User {
  @triggersSync()
  save() { ... }
  @preferCache(false)
  get displayName() { ... }
  update(@required info: Partial<User>) { ... }
}

ts 通用语法

2023-03-28 08:39
// 确保类符合一组接口或类型  ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈╮
// 子类这个类 ┈┈┈┈┈┈┈┈↘                 ┈┈┈┈┈┈┈┈┈┈┈┈┈┴┈┈┈┈┈┈┈
class User extends Account implements Updatable, Serializable {
  id: string;                     // 一个字段
  displayName?: boolean;          // 可选字段
  name!: string;                  // '相信我,它在哪里'字段
  #attributes: Map<any, any>;     // 私人字段
  roles = ["user"];               // 具有默认值的字段
  readonly createdAt = new Date() // 具有默认值的只读字段
  //  代码调用“new”
  constructor(id: string, email: string) {
    super(id);
    //  在 `strict: true` 中,会根据字段检查此代码以确保其设置正确
    this.email = email;
    // ....
  };
  //  描述类方法(和箭头函数字段)的方式
  setName(name: string) { this.name = name }
  verifyName = (name: string) => { /* ... */ }

  //  具有 2 个重载定义的函数
  sync(): Promise<{ ... }>
  sync(cb: ((result: string) => void)): void
  sync(cb?: ((result: string) => void)): void | Promise<{ ... }> {}
  //  Getters 和 setters
  get accountID() { }
  set accountID(value: string) { }
  //  私有访问只是对这个类,受保护的允许子类。 仅用于类型检查,public 是默认值。
  private makeRequest() { ... }
  protected handleRequest() { ... }
  //  静态字段/方法
  static #userCount = 0;
  static registerUser(user: User) { ... }
  //  用于设置静态变量的静态块。 ‘this’指的是静态类
  static { this.#userCount = -1 }
}

ts对象字面量语法

2023-03-28 08:34

type JSONResponse = {
  version: number;                        // 字段
  /** In bytes */                         // 附加文档
  payloadSize: number;
  outOfStock?: boolean;                   // 可选的
  update: (retryTimes: number) => void;   // 箭头函数字段
  update(retryTimes: number): void;       // 函数
  (): JSONResponse                        // 类型是可调用的
  [key: string]: number;                  // 接受任何索引
  new (s: string): JSONResponse;          // new 对象
  readonly body: string;                  // 只读属性
}

go env

2023-03-28 08:32

GOOS
编译系统
GOARCH
编译arch
GO111MODULE
gomod开关
GOPROXY
go代理 https://goproxy.io https://goproxy.cn https://mirrors.aliyun.com/goproxy/
GOSSAFUNC
生成 SSA.html 文件,展示代码优化的每一步 GOSSAFUNC=func_name go build

go module

2023-03-28 08:31
go mod init
初始化当前文件夹,创建go.mod文件
go mod download
下载依赖的module到本地
go mod tidy
增加缺少的module,删除无用的module
go mod vendor
将依赖复制到vendor下
文件 go.mod
依赖列表和版本约束
文件 go.sum
记录 module 文件 hash 值,用于安全校验

go编译器命令

2023-03-28 08:29


go command [参数]	go 命令 [参数]
go build	编译包和依赖包
go clean	移除对象和缓存文件
go doc	显示包的文档
go env	打印go的环境变量信息
go bug	报告bug
go fix	更新包使用新的api
go fmt	格式规范化代码
go generate	通过处理资源生成go文件
go get	下载并安装包及其依赖
go install	编译和安装包及其依赖
go list	列出所有包
go run	编译和运行go程序
go test	测试
go tool	运行给定的go工具
go version	显示go当前版本
go vet	发现代码中可能的错误

函数多返回值

2023-03-28 08:26

A function can return any number of results.

The swap function returns two strings. It is multiple results.


package main

import "fmt"

func swap(x, y string) (string, string) {
	return y, x
}

func main() {
	a, b := swap("hello", "world")
	fmt.Println(a, b)
}

go 闭包

2023-03-28 08:20

func outer() (func() int, int) {
    outer_var := 2
    inner := func() int {
        outer_var += 99
        return outer_var
    }
    inner()
    return inner, outer_var
}
inner, val := outer()
fmt.Println(val)
// => 101
fmt.Println(inner())
// => 200,这里涉及到golang中闭包和内存逃逸的概念,inner()实际上执行了两次,outer()中一次,fmt又一次,
//但为什么是200呢,编译器不能确定outer_var在后续会不会使用,
//所以outer_var不会随着outer()结束而释放它的栈(Stack)空间,
//而会‘逃逸到’堆(Heap)上,那么第二次的inner()中outer_var就会是101。

go fmt.Printf

2023-03-28 08:18

package main
import (
        "fmt"
        "os"
)
type point struct {
        x, y int
}
func main() {
        p := point{1, 2}
        fmt.Printf("%v\n", p)                        // => {1 2}
        fmt.Printf("%+v\n", p)                       // => {x:1 y:2}
        fmt.Printf("%#v\n", p)                       // => main.point{x:1, y:2}
        fmt.Printf("%T\n", p)                        // => main.point
        fmt.Printf("%t\n", true)                     // => TRUE
        fmt.Printf("%d\n", 123)                      // => 123
        fmt.Printf("%b\n", 14)                       // => 1110
        fmt.Printf("%c\n", 33)                       // => !
        fmt.Printf("%x\n", 456)                      // => 1c8
        fmt.Printf("%f\n", 78.9)                     // => 78.9
        fmt.Printf("%e\n", 123400000.0)              // => 1.23E+08
        fmt.Printf("%E\n", 123400000.0)              // => 1.23E+08
        fmt.Printf("%s\n", "\"string\"")             // => "string"
        fmt.Printf("%q\n", "\"string\"")             // => "\"string\""
        fmt.Printf("%x\n", "hex this")               // => 6.86578E+15
        fmt.Printf("%p\n", &p)                       // => 0xc00002c040
        fmt.Printf("|%6d|%6d|\n", 12, 345)           // => |    12|   345|
        fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45)     // => |  1.20|  3.45|
        fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45)   // => |1.20  |3.45  |
        fmt.Printf("|%6s|%6s|\n", "foo", "b")        // => |   foo|     b|
        fmt.Printf("|%-6s|%-6s|\n", "foo", "b")      // => |foo   |b     |
        s := fmt.Sprintf("a %s", "string")
        fmt.Println(s)
        fmt.Fprintf(os.Stderr, "an %s\n", "error")
}

go类型转换

2023-03-28 08:16

Go语言中不允许隐式转换,所有类型转换必须显式声明(强制转换),而且转换只能发生在两种相互兼容的类型之间。

i := 90
f := float64(i)
u := uint(i)
// 将等于字符Z
s := string(i)
如何获取int字符串?
i := 90
// 需要导入“strconv”
s := strconv.Itoa(i)
fmt.Println(s) // Outputs: 90

concat

2023-03-28 08:14

update daily1 set price= 100 * (rand()*10) *id + floor(RAND()*100) - 3.14 where id=1;

update daily1 set date= now() - interval  floor(RAND()*10) day where id%2!=0;

update daily1 set username =   concat('用户',floor(rand()*100))  where id%2!=0;

string与number

2023-03-28 08:12

update daily1 set username = concat('用户',floor(rand()*100)) where id%2!=0;

看不到我