feat: add golang.md
sheatsheet.
This commit is contained in:
parent
4122b48f76
commit
19caaad574
@ -18,6 +18,7 @@ Quick Reference
|
|||||||
[C](./docs/c.md)<!--rehype:style=background: rgb(92 107 192/var(\-\-bg\-opacity));-->
|
[C](./docs/c.md)<!--rehype:style=background: rgb(92 107 192/var(\-\-bg\-opacity));-->
|
||||||
[Docker](./docs/docker.md)<!--rehype:style=background: rgb(72 143 223/var(\-\-bg\-opacity));-->
|
[Docker](./docs/docker.md)<!--rehype:style=background: rgb(72 143 223/var(\-\-bg\-opacity));-->
|
||||||
[Dockerfile](./docs/dockerfile.md)<!--rehype:style=background: rgb(0 72 153/var(\-\-bg\-opacity));-->
|
[Dockerfile](./docs/dockerfile.md)<!--rehype:style=background: rgb(0 72 153/var(\-\-bg\-opacity));-->
|
||||||
|
[Golang](./docs/golang.md)<!--rehype:style=background: rgb(72 143 223/var(\-\-bg\-opacity));-->
|
||||||
[JSON](./docs/json.md)<!--rehype:style=background: rgb(57 59 60/var(\-\-bg\-opacity));-->
|
[JSON](./docs/json.md)<!--rehype:style=background: rgb(57 59 60/var(\-\-bg\-opacity));-->
|
||||||
[Markdown](./docs/markdown.md)<!--rehype:style=background: rgb(103 61 156/var(\-\-bg\-opacity));-->
|
[Markdown](./docs/markdown.md)<!--rehype:style=background: rgb(103 61 156/var(\-\-bg\-opacity));-->
|
||||||
[TOML](./docs/toml.md)<!--rehype:style=background: rgb(132 132 132/var(\-\-bg\-opacity));-->
|
[TOML](./docs/toml.md)<!--rehype:style=background: rgb(132 132 132/var(\-\-bg\-opacity));-->
|
||||||
|
966
docs/golang.md
Normal file
966
docs/golang.md
Normal file
@ -0,0 +1,966 @@
|
|||||||
|
Golang 备忘清单
|
||||||
|
===
|
||||||
|
|
||||||
|
该备忘单提供了帮助您使用 [Golang](https://golang.org) 的基本语法和方法。
|
||||||
|
|
||||||
|
入门
|
||||||
|
--------
|
||||||
|
|
||||||
|
### hello.go
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
import "fmt"
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Hello, world!")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
直接运行
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ go run hello.go
|
||||||
|
Hello, world!
|
||||||
|
```
|
||||||
|
|
||||||
|
或者在 [Go repl](https://repl.it/languages/go) 中尝试一下
|
||||||
|
|
||||||
|
### 变量
|
||||||
|
|
||||||
|
```go
|
||||||
|
var s1 string
|
||||||
|
s1 = "Learn Go!"
|
||||||
|
// 一次声明多个变量
|
||||||
|
var b, c int = 1, 2
|
||||||
|
var d = true
|
||||||
|
```
|
||||||
|
|
||||||
|
简短声明
|
||||||
|
|
||||||
|
```go
|
||||||
|
s1 := "Learn Go!" // string
|
||||||
|
b, c := 1, 2 // int
|
||||||
|
d := true // bool
|
||||||
|
```
|
||||||
|
|
||||||
|
参见:[基本类型](#golang-基本类型)
|
||||||
|
|
||||||
|
### 函数
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
import "fmt"
|
||||||
|
// 程序的入口点
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Hello world!")
|
||||||
|
say("Hello Go!")
|
||||||
|
}
|
||||||
|
func say(message string) {
|
||||||
|
fmt.Println("You said: ", message)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
参见:[函数(Functions)](#golang-函数)
|
||||||
|
|
||||||
|
### 注释
|
||||||
|
|
||||||
|
```go
|
||||||
|
// 单行注释
|
||||||
|
/* 这是
|
||||||
|
多行注释 */
|
||||||
|
```
|
||||||
|
|
||||||
|
### 如果语句
|
||||||
|
|
||||||
|
```go
|
||||||
|
if true {
|
||||||
|
fmt.Println("Yes!")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
参见:[条件控制](#golang-条件控制)
|
||||||
|
|
||||||
|
Golang 基本类型
|
||||||
|
--------
|
||||||
|
|
||||||
|
### 字符串 Strings
|
||||||
|
|
||||||
|
```go
|
||||||
|
s1 := "Hello" + "World"
|
||||||
|
s2 := `A "raw" string literal
|
||||||
|
can include line breaks.`
|
||||||
|
// 输出:11
|
||||||
|
fmt.Println(len(s1))
|
||||||
|
// 输出:Hello
|
||||||
|
fmt.Println(string(s1[0:5]))
|
||||||
|
```
|
||||||
|
|
||||||
|
字符串的类型为 `字符串`
|
||||||
|
|
||||||
|
### 数字 Numbers
|
||||||
|
|
||||||
|
```go
|
||||||
|
num := 3 // int
|
||||||
|
num := 3. // float64
|
||||||
|
num := 3 + 4i // complex128
|
||||||
|
num := byte('a') // byte (alias: uint8)
|
||||||
|
var u uint = 7 // uint (unsigned)
|
||||||
|
var p float32 = 22.7 // 32-bit float
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 操作符 Operators
|
||||||
|
|
||||||
|
```go
|
||||||
|
x := 5
|
||||||
|
x++
|
||||||
|
fmt.Println("x + 4 =", x + 4)
|
||||||
|
fmt.Println("x * 4 =", x * 4)
|
||||||
|
```
|
||||||
|
|
||||||
|
参见:[更多操作符](#运算符和标点符号)
|
||||||
|
|
||||||
|
### 布尔值 Booleans
|
||||||
|
|
||||||
|
```go
|
||||||
|
isTrue := true
|
||||||
|
isFalse := false
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 操作符
|
||||||
|
|
||||||
|
```go
|
||||||
|
fmt.Println(true && true) // true
|
||||||
|
fmt.Println(true && false) // false
|
||||||
|
fmt.Println(true || true) // true
|
||||||
|
fmt.Println(true || false) // true
|
||||||
|
fmt.Println(!true) // false
|
||||||
|
```
|
||||||
|
|
||||||
|
参见:[更多操作符](#运算符和标点符号)
|
||||||
|
|
||||||
|
### 数组 Arrays
|
||||||
|
<!--rehype:wrap-class=row-span-2-->
|
||||||
|
|
||||||
|
```go
|
||||||
|
┌────┬────┬────┬────┬─────┬─────┐
|
||||||
|
| 2 | 3 | 5 | 7 | 11 | 13 |
|
||||||
|
└────┴────┴────┴────┴─────┴─────┘
|
||||||
|
0 1 2 3 4 5
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```go
|
||||||
|
primes := [...]int{2, 3, 5, 7, 11, 13}
|
||||||
|
fmt.Println(len(primes)) // => 6
|
||||||
|
// 输出:[2 3 5 7 11 13]
|
||||||
|
fmt.Println(primes)
|
||||||
|
// 与 [:3] 相同,输出:[2 3 5]
|
||||||
|
fmt.Println(primes[0:3])
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```go
|
||||||
|
var a [2]string
|
||||||
|
a[0] = "Hello"
|
||||||
|
a[1] = "World"
|
||||||
|
fmt.Println(a[0], a[1]) //=> Hello World
|
||||||
|
fmt.Println(a) // => [Hello World]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2d array
|
||||||
|
|
||||||
|
```go
|
||||||
|
var twoDimension [2][3]int
|
||||||
|
for i := 0; i < 2; i++ {
|
||||||
|
for j := 0; j < 3; j++ {
|
||||||
|
twoDimension[i][j] = i + j
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// => 2d: [[0 1 2] [1 2 3]]
|
||||||
|
fmt.Println("2d: ", twoDimension)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 指针(Pointers)
|
||||||
|
|
||||||
|
```go
|
||||||
|
func main () {
|
||||||
|
b := *getPointer()
|
||||||
|
fmt.Println("Value is", b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPointer () (myPointer *int) {
|
||||||
|
a := 234
|
||||||
|
return &a
|
||||||
|
}
|
||||||
|
|
||||||
|
a := new(int)
|
||||||
|
*a = 234
|
||||||
|
```
|
||||||
|
|
||||||
|
参见:[指针(Pointers)](https://tour.golang.org/moretypes/1)
|
||||||
|
|
||||||
|
### 切片(Slices)
|
||||||
|
|
||||||
|
```go
|
||||||
|
s := make([]string, 3)
|
||||||
|
s[0] = "a"
|
||||||
|
s[1] = "b"
|
||||||
|
s = append(s, "d")
|
||||||
|
s = append(s, "e", "f")
|
||||||
|
fmt.Println(s)
|
||||||
|
fmt.Println(s[1])
|
||||||
|
fmt.Println(len(s))
|
||||||
|
fmt.Println(s[1:3])
|
||||||
|
slice := []int{2, 3, 4}
|
||||||
|
```
|
||||||
|
|
||||||
|
另见:[切片示例](https://gobyexample.com/slices)
|
||||||
|
|
||||||
|
### 常量(Constants)
|
||||||
|
|
||||||
|
```go
|
||||||
|
const s string = "constant"
|
||||||
|
const Phi = 1.618
|
||||||
|
const n = 500000000
|
||||||
|
const d = 3e20 / n
|
||||||
|
fmt.Println(d)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 类型转换
|
||||||
|
|
||||||
|
```go
|
||||||
|
i := 90
|
||||||
|
f := float64(i)
|
||||||
|
u := uint(i)
|
||||||
|
// 将等于字符Z
|
||||||
|
s := string(i)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 如何获取int字符串?
|
||||||
|
|
||||||
|
```go
|
||||||
|
i := 90
|
||||||
|
// 需要导入“strconv”
|
||||||
|
s := strconv.Itoa(i)
|
||||||
|
fmt.Println(s) // Outputs: 90
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Golang 字符串
|
||||||
|
--------
|
||||||
|
|
||||||
|
### 字符串函数
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
s "strings"
|
||||||
|
)
|
||||||
|
func main() {
|
||||||
|
/* 需要将字符串导入为 s */
|
||||||
|
fmt.Println(s.Contains("test", "e"))
|
||||||
|
/* 内置 */
|
||||||
|
fmt.Println(len("hello")) // => 5
|
||||||
|
// 输出: 101
|
||||||
|
fmt.Println("hello"[1])
|
||||||
|
// 输出: e
|
||||||
|
fmt.Println(string("hello"[1]))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### fmt.Printf
|
||||||
|
<!--rehype:wrap-class=row-span-2 col-span-2-->
|
||||||
|
|
||||||
|
```go
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
另见:[fmt](https://golang.org/pkg/fmt/)
|
||||||
|
|
||||||
|
### 函数实例
|
||||||
|
|
||||||
|
| 实例 | Result |
|
||||||
|
|-------------------------------|-------------|
|
||||||
|
| Contains("test", "es") | true |
|
||||||
|
| Count("test", "t") | 2 |
|
||||||
|
| HasPrefix("test", "te") | true |
|
||||||
|
| HasSuffix("test", "st") | true |
|
||||||
|
| Index("test", "e") | 1 |
|
||||||
|
| Join([]string{"a", "b"}, "-") | a-b |
|
||||||
|
| Repeat("a", 5) | aaaaa |
|
||||||
|
| Replace("foo", "o", "0", -1) | f00 |
|
||||||
|
| Replace("foo", "o", "0", 1) | f0o |
|
||||||
|
| Split("a-b-c-d-e", "-") | [a b c d e] |
|
||||||
|
| ToLower("TEST") | test |
|
||||||
|
| ToUpper("test") | TEST |
|
||||||
|
|
||||||
|
Golang 条件控制
|
||||||
|
--------
|
||||||
|
|
||||||
|
### 有条件的
|
||||||
|
|
||||||
|
```go
|
||||||
|
a := 10
|
||||||
|
if a > 20 {
|
||||||
|
fmt.Println(">")
|
||||||
|
} else if a < 20 {
|
||||||
|
fmt.Println("<")
|
||||||
|
} else {
|
||||||
|
fmt.Println("=")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### if 中的语句
|
||||||
|
|
||||||
|
```go
|
||||||
|
x := "hello go!"
|
||||||
|
if count := len(x); count > 0 {
|
||||||
|
fmt.Println("Yes")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```go
|
||||||
|
if _, err := doThing(); err != nil {
|
||||||
|
fmt.Println("Uh oh")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Switch
|
||||||
|
|
||||||
|
```go
|
||||||
|
x := 42.0
|
||||||
|
switch x {
|
||||||
|
case 0:
|
||||||
|
case 1, 2:
|
||||||
|
fmt.Println("Multiple matches")
|
||||||
|
case 42: // Don't "fall through".
|
||||||
|
fmt.Println("reached")
|
||||||
|
case 43:
|
||||||
|
fmt.Println("Unreached")
|
||||||
|
default:
|
||||||
|
fmt.Println("Optional")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
参见:[Switch](https://github.com/golang/go/wiki/Switch)
|
||||||
|
|
||||||
|
### For loop
|
||||||
|
|
||||||
|
```go
|
||||||
|
for i := 0; i <= 10; i++ {
|
||||||
|
fmt.Println("i: ", i)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 对于 Range 循环
|
||||||
|
|
||||||
|
```go
|
||||||
|
nums := []int{2, 3, 4}
|
||||||
|
sum := 0
|
||||||
|
for _, num := range nums {
|
||||||
|
sum += num
|
||||||
|
}
|
||||||
|
fmt.Println("sum:", sum)
|
||||||
|
```
|
||||||
|
|
||||||
|
### While 循环
|
||||||
|
|
||||||
|
```go
|
||||||
|
i := 1
|
||||||
|
for i <= 3 {
|
||||||
|
fmt.Println(i)
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Continue 关键字
|
||||||
|
|
||||||
|
```go
|
||||||
|
for i := 0; i <= 5; i++ {
|
||||||
|
if i % 2 == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fmt.Println(i)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Break 关键字
|
||||||
|
|
||||||
|
```go
|
||||||
|
for {
|
||||||
|
fmt.Println("loop")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Golang 结构和映射
|
||||||
|
--------
|
||||||
|
|
||||||
|
### 定义
|
||||||
|
<!--rehype:wrap-class=row-span-2-->
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
type Vertex struct {
|
||||||
|
X int
|
||||||
|
Y int
|
||||||
|
}
|
||||||
|
func main() {
|
||||||
|
v := Vertex{1, 2}
|
||||||
|
v.X = 4
|
||||||
|
fmt.Println(v.X, v.Y) // => 4 2
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
参见:[结构(Structs)](https://tour.golang.org/moretypes/2)
|
||||||
|
|
||||||
|
### 字面量
|
||||||
|
|
||||||
|
```go
|
||||||
|
v := Vertex{X: 1, Y: 2}
|
||||||
|
// Field names can be omitted
|
||||||
|
v := Vertex{1, 2}
|
||||||
|
// Y is implicit
|
||||||
|
v := Vertex{X: 1}
|
||||||
|
```
|
||||||
|
|
||||||
|
您还可以输入字段名
|
||||||
|
|
||||||
|
### 映射
|
||||||
|
<!--rehype:wrap-class=row-span-2-->
|
||||||
|
|
||||||
|
```go
|
||||||
|
m := make(map[string]int)
|
||||||
|
m["k1"] = 7
|
||||||
|
m["k2"] = 13
|
||||||
|
fmt.Println(m) // => map[k1:7 k2:13]
|
||||||
|
v1 := m["k1"]
|
||||||
|
fmt.Println(v1) // => 7
|
||||||
|
fmt.Println(len(m)) // => 2
|
||||||
|
delete(m, "k2")
|
||||||
|
fmt.Println(m) // => map[k1:7]
|
||||||
|
_, prs := m["k2"]
|
||||||
|
fmt.Println(prs) // => false
|
||||||
|
n := map[string]int{"foo": 1, "bar": 2}
|
||||||
|
fmt.Println(n) // => map[bar:2 foo:1]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 指向结构的指针
|
||||||
|
|
||||||
|
```go
|
||||||
|
v := &Vertex{1, 2}
|
||||||
|
v.X = 2
|
||||||
|
```
|
||||||
|
|
||||||
|
Doing `v.X` is the same as doing `(*v).X`, when `v` is a pointer.
|
||||||
|
|
||||||
|
Golang 函数
|
||||||
|
--------
|
||||||
|
|
||||||
|
### 多个参数
|
||||||
|
|
||||||
|
```go
|
||||||
|
func plus(a int, b int) int {
|
||||||
|
return a + b
|
||||||
|
}
|
||||||
|
func plusPlus(a, b, c int) int {
|
||||||
|
return a + b + c
|
||||||
|
}
|
||||||
|
fmt.Println(plus(1, 2))
|
||||||
|
fmt.Println(plusPlus(1, 2, 3))
|
||||||
|
```
|
||||||
|
|
||||||
|
### 多次返回
|
||||||
|
|
||||||
|
```go
|
||||||
|
func vals() (int, int) {
|
||||||
|
return 3, 7
|
||||||
|
}
|
||||||
|
a, b := vals()
|
||||||
|
fmt.Println(a) // => 3
|
||||||
|
fmt.Println(b) // => 7
|
||||||
|
```
|
||||||
|
|
||||||
|
### 匿名函数
|
||||||
|
|
||||||
|
```go
|
||||||
|
r1, r2 := func() (string, string) {
|
||||||
|
x := []string{"hello", "world"}
|
||||||
|
return x[0], x[1]
|
||||||
|
}()
|
||||||
|
// => hello world
|
||||||
|
fmt.Println(r1, r2)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 命名返回
|
||||||
|
|
||||||
|
```go
|
||||||
|
func split(sum int) (x, y int) {
|
||||||
|
x = sum * 4 / 9
|
||||||
|
y = sum - x
|
||||||
|
return
|
||||||
|
}
|
||||||
|
x, y := split(17)
|
||||||
|
fmt.Println(x) // => 7
|
||||||
|
fmt.Println(y) // => 10
|
||||||
|
```
|
||||||
|
|
||||||
|
### 变量函数
|
||||||
|
|
||||||
|
```go
|
||||||
|
func sum(nums ...int) {
|
||||||
|
fmt.Print(nums, " ")
|
||||||
|
total := 0
|
||||||
|
for _, num := range nums {
|
||||||
|
total += num
|
||||||
|
}
|
||||||
|
fmt.Println(total)
|
||||||
|
}
|
||||||
|
sum(1, 2) //=> [1 2] 3
|
||||||
|
sum(1, 2, 3) // => [1 2 3] 6
|
||||||
|
nums := []int{1, 2, 3, 4}
|
||||||
|
sum(nums...) // => [1 2 3 4] 10
|
||||||
|
```
|
||||||
|
|
||||||
|
### 初始化函数
|
||||||
|
|
||||||
|
```go
|
||||||
|
import --> const --> var --> init()
|
||||||
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
```go
|
||||||
|
var num = setNumber()
|
||||||
|
func setNumber() int {
|
||||||
|
return 42
|
||||||
|
}
|
||||||
|
func init() {
|
||||||
|
num = 0
|
||||||
|
}
|
||||||
|
func main() {
|
||||||
|
fmt.Println(num) // => 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 作为值的函数
|
||||||
|
|
||||||
|
```go
|
||||||
|
func main() {
|
||||||
|
// 将函数赋给名称
|
||||||
|
add := func(a, b int) int {
|
||||||
|
return a + b
|
||||||
|
}
|
||||||
|
// 使用名称调用函数
|
||||||
|
fmt.Println(add(3, 4)) // => 7
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 关闭 1
|
||||||
|
|
||||||
|
```go
|
||||||
|
func scope() func() int{
|
||||||
|
outer_var := 2
|
||||||
|
foo := func() int {return outer_var}
|
||||||
|
return foo
|
||||||
|
}
|
||||||
|
// Outpus: 2
|
||||||
|
fmt.Println(scope()())
|
||||||
|
```
|
||||||
|
|
||||||
|
### 关闭 2
|
||||||
|
|
||||||
|
```go
|
||||||
|
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(inner()) // => 200
|
||||||
|
fmt.Println(val) // => 101
|
||||||
|
```
|
||||||
|
|
||||||
|
Golang 包(Packages)
|
||||||
|
--------
|
||||||
|
|
||||||
|
### 导入
|
||||||
|
<!--rehype:wrap-class=row-span-2-->
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "fmt"
|
||||||
|
import "math/rand"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 等同于
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt" // 给 fmt.Println
|
||||||
|
"math/rand" // 给 rand.Intn
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
另见:[导入](https://tour.golang.org/basics/1)
|
||||||
|
|
||||||
|
### 别名
|
||||||
|
<!--rehype:wrap-class=row-span-2-->
|
||||||
|
|
||||||
|
```go
|
||||||
|
import r "math/rand"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
r "math/rand"
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```go
|
||||||
|
r.Intn()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Packages
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
// 一个内部包只能被另一个包导入
|
||||||
|
// 那是在以内部目录的父级为根的树内
|
||||||
|
package internal
|
||||||
|
```
|
||||||
|
|
||||||
|
另见:[内部包](https://go.dev/doc/go1.4#internalpackages)
|
||||||
|
|
||||||
|
### 导出名称
|
||||||
|
|
||||||
|
```go
|
||||||
|
// 以大写字母开头
|
||||||
|
func Hello () {
|
||||||
|
···
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
另见:[导出的名称](https://tour.golang.org/basics/3)
|
||||||
|
|
||||||
|
Golang 并发
|
||||||
|
--------
|
||||||
|
|
||||||
|
### 协程
|
||||||
|
<!--rehype:wrap-class=row-span-2-->
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
func f(from string) {
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
fmt.Println(from, ":", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func main() {
|
||||||
|
f("direct")
|
||||||
|
go f("goroutine")
|
||||||
|
go func(msg string) {
|
||||||
|
fmt.Println(msg)
|
||||||
|
}("going")
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
fmt.Println("done")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
参见:[Goroutines](https://tour.golang.org/concurrency/1), [Channels](https://tour.golang.org/concurrency/2)
|
||||||
|
|
||||||
|
### WaitGroup
|
||||||
|
<!--rehype:wrap-class=row-span-2-->
|
||||||
|
|
||||||
|
```golang
|
||||||
|
package main
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
func w(id int, wg *sync.WaitGroup) {
|
||||||
|
defer wg.Done()
|
||||||
|
fmt.Printf("%d starting\n", id)
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
fmt.Printf("%d done\n", id)
|
||||||
|
}
|
||||||
|
func main() {
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
for i := 1; i <= 5; i++ {
|
||||||
|
wg.Add(1)
|
||||||
|
go w(i, &wg)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
参见:[WaitGroup](https://golang.org/pkg/sync/#WaitGroup)
|
||||||
|
|
||||||
|
### Closing channels
|
||||||
|
|
||||||
|
```go
|
||||||
|
ch <- 1
|
||||||
|
ch <- 2
|
||||||
|
ch <- 3
|
||||||
|
close(ch) // 关闭频道
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```go
|
||||||
|
// 迭代通道直到关闭
|
||||||
|
for i := range ch {
|
||||||
|
···
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Closed if `ok == false`
|
||||||
|
v, ok := <- ch
|
||||||
|
```
|
||||||
|
|
||||||
|
参见:[范围和关闭](https://tour.golang.org/concurrency/4)
|
||||||
|
|
||||||
|
### 缓冲通道
|
||||||
|
|
||||||
|
```go
|
||||||
|
ch := make(chan int, 2)
|
||||||
|
ch <- 1
|
||||||
|
ch <- 2
|
||||||
|
ch <- 3
|
||||||
|
// 致命错误:
|
||||||
|
// 所有 goroutine 都处于休眠状态 - 死锁
|
||||||
|
```
|
||||||
|
|
||||||
|
参见:[缓冲通道](https://tour.golang.org/concurrency/3)
|
||||||
|
|
||||||
|
Golang 错误控制
|
||||||
|
--------
|
||||||
|
|
||||||
|
### 延迟函数
|
||||||
|
|
||||||
|
```go
|
||||||
|
func main() {
|
||||||
|
defer func() {
|
||||||
|
fmt.Println("Done")
|
||||||
|
}()
|
||||||
|
fmt.Println("Working...")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lambda defer
|
||||||
|
|
||||||
|
```go
|
||||||
|
func main() {
|
||||||
|
var d = int64(0)
|
||||||
|
defer func(d *int64) {
|
||||||
|
fmt.Printf("& %v Unix Sec\n", *d)
|
||||||
|
}(&d)
|
||||||
|
fmt.Print("Done ")
|
||||||
|
d = time.Now().Unix()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`defer` 函数使用当前值`d`,除非我们使用指针在 `main` 末尾获取最终值
|
||||||
|
|
||||||
|
### Defer
|
||||||
|
|
||||||
|
```go
|
||||||
|
func main() {
|
||||||
|
defer fmt.Println("Done")
|
||||||
|
fmt.Println("Working...")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
参见:[Defer, panic and recover](https://blog.golang.org/defer-panic-and-recover)
|
||||||
|
|
||||||
|
Golang 方法(Methods)
|
||||||
|
--------
|
||||||
|
<!--rehype:body-class=cols-2-->
|
||||||
|
|
||||||
|
### 接收器
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Vertex struct {
|
||||||
|
X, Y float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v Vertex) Abs() float64 {
|
||||||
|
return math.Sqrt(v.X * v.X + v.Y * v.Y)
|
||||||
|
}
|
||||||
|
|
||||||
|
v := Vertex{1, 2}
|
||||||
|
v.Abs()
|
||||||
|
```
|
||||||
|
|
||||||
|
参见:[Methods](https://tour.golang.org/methods/1)
|
||||||
|
|
||||||
|
### Mutation
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (v *Vertex) Scale(f float64) {
|
||||||
|
v.X = v.X * f
|
||||||
|
v.Y = v.Y * f
|
||||||
|
}
|
||||||
|
|
||||||
|
v := Vertex{6, 12}
|
||||||
|
v.Scale(0.5)
|
||||||
|
// `v` 已更新
|
||||||
|
```
|
||||||
|
|
||||||
|
参见:[指针接收器](https://tour.golang.org/methods/4)
|
||||||
|
|
||||||
|
Golang 接口(Interfaces)
|
||||||
|
--------
|
||||||
|
<!--rehype:body-class=cols-2-->
|
||||||
|
|
||||||
|
### 基本接口(Interfaces)
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Shape interface {
|
||||||
|
Area() float64
|
||||||
|
Perimeter() float64
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 结构(Struct)
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Rectangle struct {
|
||||||
|
Length, Width float64
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
结构 `Rectangle` 通过实现其所有方法隐式实现接口 `Shape`
|
||||||
|
|
||||||
|
### 方法(Methods)
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (r Rectangle) Area() float64 {
|
||||||
|
return r.Length * r.Width
|
||||||
|
}
|
||||||
|
func (r Rectangle) Perimeter() float64 {
|
||||||
|
return 2 * (r.Length + r.Width)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
在 `Shape` 中定义的方法在`Rectangle`中实现
|
||||||
|
|
||||||
|
### 接口实例
|
||||||
|
|
||||||
|
```go
|
||||||
|
func main() {
|
||||||
|
var r Shape = Rectangle{Length: 3, Width: 4}
|
||||||
|
fmt.Printf("Type of r: %T, Area: %v, Perimeter: %v.", r, r.Area(), r.Perimeter())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
<!--rehype:className=wrap-text -->
|
||||||
|
|
||||||
|
杂项
|
||||||
|
-------------
|
||||||
|
|
||||||
|
### 关键字(Keywords)
|
||||||
|
- break
|
||||||
|
- default
|
||||||
|
- func
|
||||||
|
- interface
|
||||||
|
- select
|
||||||
|
- case
|
||||||
|
- defer
|
||||||
|
- go
|
||||||
|
- map
|
||||||
|
- struct
|
||||||
|
- chan
|
||||||
|
- else
|
||||||
|
- goto
|
||||||
|
- package
|
||||||
|
- switch
|
||||||
|
- const
|
||||||
|
- fallthrough
|
||||||
|
- if
|
||||||
|
- range
|
||||||
|
- type
|
||||||
|
- continue
|
||||||
|
- for
|
||||||
|
- import
|
||||||
|
- return
|
||||||
|
- var
|
||||||
|
<!--rehype:className=cols-3 style-none-->
|
||||||
|
|
||||||
|
### 运算符和标点符号
|
||||||
|
|
||||||
|
| | | | | | | | | |
|
||||||
|
|---|----|-----|-----|------|----|-----|---|---|
|
||||||
|
| `+` | & | += | &= | && | == | != | ( | ) |
|
||||||
|
| `-` | \| | -= | \|= | \|\| | < | <= | [ | ] |
|
||||||
|
| `*` | ^ | *= | ^= | <- | > | >= | { | } |
|
||||||
|
| `/` | << | /= | <<= | ++ | = | := | , | ; |
|
||||||
|
| `%` | >> | %= | >>= | -- | ! | ... | . | : |
|
||||||
|
| | &^ | &^= | | | | | | |
|
||||||
|
|
||||||
|
另见
|
||||||
|
--------
|
||||||
|
- [Devhints](https://devhints.io/go) _(devhints.io)_
|
||||||
|
- [A tour of Go](https://tour.golang.org/welcome/1) _(tour.golang.org)_
|
||||||
|
- [Golang wiki](https://github.com/golang/go/wiki/) _(github.com)_
|
||||||
|
- [Effective Go](https://golang.org/doc/effective_go.html) _(golang.org)_
|
||||||
|
- [Go by Example](https://gobyexample.com/) _(gobyexample.com)_
|
||||||
|
- [Awesome Go](https://awesome-go.com/) _(awesome-go.com)_
|
||||||
|
- [JustForFunc Youtube](https://www.youtube.com/channel/UC_BzFbxG2za3bp5NRRRXJSw) _(youtube.com)_
|
||||||
|
- [Style Guide](https://github.com/golang/go/wiki/CodeReviewComments) _(github.com)_
|
1
scripts/assets/golang.svg
Normal file
1
scripts/assets/golang.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 120 120"><path fill="currentColor" d="M60,0 C93.137085,-6.08718376e-15 120,26.862915 120,60 C120,93.137085 93.137085,120 60,120 C26.862915,120 4.05812251e-15,93.137085 0,60 C-4.05812251e-15,26.862915 26.862915,6.08718376e-15 60,0 Z M66.9375,44.8284375 C63.140625,42.2503125 58.921875,41.7346875 54.515625,42.5315625 C49.125,43.5159375 44.71875,46.2815625 41.390625,50.6409375 C38.296875,54.6721875 36.796875,59.2659375 37.40625,64.3753125 C37.921875,68.6878125 39.890625,72.1565625 43.359375,74.7815625 C47.109375,77.5940625 51.375,78.4846875 55.96875,77.8753125 C61.546875,77.1253125 65.953125,74.3596875 69.328125,69.9065625 C70.0941964,68.8967411 70.7503316,67.8351849 71.2989326,66.7266981 C72.0855742,69.5828677 73.6756442,72.0358799 75.984375,74.0315625 C79.265625,76.8440625 83.15625,78.0628125 87.421875,78.1565625 C88.640625,78.0159375 89.90625,77.9690625 91.171875,77.7346875 C95.53125,76.8440625 99.328125,74.8753125 102.421875,71.7346875 C106.78125,67.3284375 108.609375,62.1721875 107.8125,55.8440625 C107.203125,51.3440625 104.90625,47.9221875 101.203125,45.3909375 C97.125,42.6253125 92.625,42.1565625 87.84375,43.0003125 C82.265625,43.9846875 78.140625,46.3284375 74.71875,50.8284375 C73.2524636,52.7475477 72.1531891,54.7757695 71.4756823,56.9222289 L56.390625,56.9221875 C55.6875,56.9221875 55.359375,57.3909375 55.21875,57.6721875 C54.5625,58.8909375 53.4375,61.3284375 52.828125,62.7815625 C52.5,63.5784375 52.734375,64.1878125 53.71875,64.1878125 L62.765625,64.1878125 C62.296875,64.8440625 61.921875,65.4065625 61.5,65.9221875 C59.390625,68.3128125 56.71875,69.4378125 53.53125,69.0159375 C49.828125,68.5003125 47.25,65.4065625 47.203125,61.6565625 C47.15625,57.8596875 48.796875,54.8128125 51.984375,52.7503125 C54.65625,51.0159375 57.515625,50.5940625 60.46875,52.0471875 C61.453125,52.5159375 61.96875,53.0315625 62.671875,53.8284375 C63.28125,54.5315625 63.328125,54.4846875 64.03125,54.2971875 C66.9375,53.5471875 68.953125,52.9846875 71.90625,52.2346875 C72.46875,52.0940625 72.65625,51.8596875 72.375,51.4378125 C71.203125,48.7190625 69.421875,46.4690625 66.9375,44.8284375 Z M88.875,51.4378125 C93.328125,50.4065625 97.59375,53.0315625 98.4375,57.6721875 C98.53125,58.1409375 98.53125,58.6096875 98.578125,59.2190625 C98.34375,63.2503125 96.328125,66.2503125 92.625,68.1721875 C90.140625,69.4378125 87.5625,69.5784375 84.984375,68.4534375 C81.609375,66.9534375 79.828125,63.2503125 80.671875,59.5940625 C81.703125,55.1878125 84.515625,52.4221875 88.875,51.4378125 Z M33.609375,59.9690625 L24.234375,59.9690625 C24.046875,59.9690625 23.859375,60.1096875 23.765625,60.2503125 L23.109375,61.4221875 C23.015625,61.5628125 23.0625,61.7034375 23.25,61.7034375 L33.46875,61.7503125 C33.609375,61.7503125 33.796875,61.6096875 33.796875,61.4221875 L33.890625,60.2971875 C33.890625,60.1096875 33.796875,59.9690625 33.609375,59.9690625 Z M34.640625,55.6565625 L13.265625,55.6565625 C13.078125,55.6565625 12.84375,55.7503125 12.75,55.8909375 L11.765625,57.1565625 C11.671875,57.2971875 11.71875,57.3909375 11.90625,57.3909375 L34.078125,57.3440625 C34.265625,57.3440625 34.453125,57.2503125 34.5,57.0628125 L34.875,55.9378125 C34.921875,55.7971875 34.828125,55.6565625 34.640625,55.6565625 Z M37.078125,51.3440625 L20.34375,51.3440625 C20.15625,51.3440625 19.921875,51.4378125 19.828125,51.5784375 L18.84375,52.8440625 C18.75,52.9846875 18.796875,53.0784375 18.984375,53.0784375 L35.953125,53.1253125 C36.09375,53.1253125 36.328125,52.9846875 36.421875,52.8440625 L37.21875,51.6253125 C37.3125,51.4846875 37.265625,51.3440625 37.078125,51.3440625 Z"/></svg>
|
After Width: | Height: | Size: 3.6 KiB |
Loading…
x
Reference in New Issue
Block a user