Golang 备忘清单

该备忘单提供了帮助您使用 Golang 的基本语法和方法。

入门

hello.go

  1. package main
  2. import "fmt"
  3. func main() {
  4. fmt.Println("Hello, world!")
  5. }

直接运行

  1. $ go run hello.go
  2. Hello, world!

或者在 Go repl 中尝试一下

变量

  1. var s1 string
  2. s1 = "Learn Go!"
  3. // 一次声明多个变量
  4. var b, c int = 1, 2
  5. var d = true

简短声明

  1. s1 := "Learn Go!" // string
  2. b, c := 1, 2 // int
  3. d := true // bool

参见:基本类型

函数

  1. package main
  2. import "fmt"
  3. // 程序的入口点
  4. func main() {
  5. fmt.Println("Hello world!")
  6. say("Hello Go!")
  7. }
  8. func say(message string) {
  9. fmt.Println("You said: ", message)
  10. }

参见:函数(Functions)

注释

  1. // 单行注释
  2. /* 这是
  3. 多行注释 */

如果语句

  1. if true {
  2. fmt.Println("Yes!")
  3. }

参见:条件控制

Golang 基本类型

字符串 Strings

  1. s1 := "Hello" + "World"
  2. s2 := `A "raw" string literal
  3. can include line breaks.`
  4. // 输出:11
  5. fmt.Println(len(s1))
  6. // 输出:Hello
  7. fmt.Println(string(s1[0:5]))

字符串的类型为 字符串

数字 Numbers

  1. num := 3 // int
  2. num := 3. // float64
  3. num := 3 + 4i // complex128
  4. num := byte('a') // byte (alias: uint8)
  5. var u uint = 7 // uint (unsigned)
  6. var p float32 = 22.7 // 32-bit float

操作符 Operators

  1. x := 5
  2. x++
  3. fmt.Println("x + 4 =", x + 4)
  4. fmt.Println("x * 4 =", x * 4)

参见:更多操作符

布尔值 Booleans

  1. isTrue := true
  2. isFalse := false

操作符

  1. fmt.Println(true && true) // true
  2. fmt.Println(true && false) // false
  3. fmt.Println(true || true) // true
  4. fmt.Println(true || false) // true
  5. fmt.Println(!true) // false

参见:更多操作符

数组 Arrays

  1. ┌────┬────┬────┬────┬─────┬─────┐
  2. | 2 | 3 | 5 | 7 | 11 | 13 |
  3. └────┴────┴────┴────┴─────┴─────┘
  4. 0 1 2 3 4 5

  1. primes := [...]int{2, 3, 5, 7, 11, 13}
  2. fmt.Println(len(primes)) // => 6
  3. // 输出:[2 3 5 7 11 13]
  4. fmt.Println(primes)
  5. // 与 [:3] 相同,输出:[2 3 5]
  6. fmt.Println(primes[0:3])

  1. var a [2]string
  2. a[0] = "Hello"
  3. a[1] = "World"
  4. fmt.Println(a[0], a[1]) //=> Hello World
  5. fmt.Println(a) // => [Hello World]

2d array

  1. var twoDimension [2][3]int
  2. for i := 0; i < 2; i++ {
  3. for j := 0; j < 3; j++ {
  4. twoDimension[i][j] = i + j
  5. }
  6. }
  7. // => 2d: [[0 1 2] [1 2 3]]
  8. fmt.Println("2d: ", twoDimension)

指针(Pointers)

  1. func main () {
  2. b := *getPointer()
  3. fmt.Println("Value is", b)
  4. }
  5. func getPointer () (myPointer *int) {
  6. a := 234
  7. return &a
  8. }
  9. a := new(int)
  10. *a = 234

参见:指针(Pointers)

切片(Slices)

  1. s := make([]string, 3)
  2. s[0] = "a"
  3. s[1] = "b"
  4. s = append(s, "d")
  5. s = append(s, "e", "f")
  6. fmt.Println(s)
  7. fmt.Println(s[1])
  8. fmt.Println(len(s))
  9. fmt.Println(s[1:3])
  10. slice := []int{2, 3, 4}

另见:切片示例

常量(Constants)

  1. const s string = "constant"
  2. const Phi = 1.618
  3. const n = 500000000
  4. const d = 3e20 / n
  5. fmt.Println(d)

类型转换

  1. i := 90
  2. f := float64(i)
  3. u := uint(i)
  4. // 将等于字符Z
  5. s := string(i)

如何获取int字符串?

  1. i := 90
  2. // 需要导入“strconv”
  3. s := strconv.Itoa(i)
  4. fmt.Println(s) // Outputs: 90

Golang 字符串

字符串函数

  1. package main
  2. import (
  3. "fmt"
  4. s "strings"
  5. )
  6. func main() {
  7. /* 需要将字符串导入为 s */
  8. fmt.Println(s.Contains("test", "e"))
  9. /* 内置 */
  10. fmt.Println(len("hello")) // => 5
  11. // 输出: 101
  12. fmt.Println("hello"[1])
  13. // 输出: e
  14. fmt.Println(string("hello"[1]))
  15. }

fmt.Printf

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. )
  6. type point struct {
  7. x, y int
  8. }
  9. func main() {
  10. p := point{1, 2}
  11. fmt.Printf("%v\n", p) // => {1 2}
  12. fmt.Printf("%+v\n", p) // => {x:1 y:2}
  13. fmt.Printf("%#v\n", p) // => main.point{x:1, y:2}
  14. fmt.Printf("%T\n", p) // => main.point
  15. fmt.Printf("%t\n", true) // => TRUE
  16. fmt.Printf("%d\n", 123) // => 123
  17. fmt.Printf("%b\n", 14) // => 1110
  18. fmt.Printf("%c\n", 33) // => !
  19. fmt.Printf("%x\n", 456) // => 1c8
  20. fmt.Printf("%f\n", 78.9) // => 78.9
  21. fmt.Printf("%e\n", 123400000.0) // => 1.23E+08
  22. fmt.Printf("%E\n", 123400000.0) // => 1.23E+08
  23. fmt.Printf("%s\n", "\"string\"") // => "string"
  24. fmt.Printf("%q\n", "\"string\"") // => "\"string\""
  25. fmt.Printf("%x\n", "hex this") // => 6.86578E+15
  26. fmt.Printf("%p\n", &p) // => 0xc00002c040
  27. fmt.Printf("|%6d|%6d|\n", 12, 345) // => | 12| 345|
  28. fmt.Printf("|%6.2f|%6.2f|\n", 1.2, 3.45) // => | 1.20| 3.45|
  29. fmt.Printf("|%-6.2f|%-6.2f|\n", 1.2, 3.45) // => |1.20 |3.45 |
  30. fmt.Printf("|%6s|%6s|\n", "foo", "b") // => | foo| b|
  31. fmt.Printf("|%-6s|%-6s|\n", "foo", "b") // => |foo |b |
  32. s := fmt.Sprintf("a %s", "string")
  33. fmt.Println(s)
  34. fmt.Fprintf(os.Stderr, "an %s\n", "error")
  35. }

另见: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 条件控制

有条件的

  1. a := 10
  2. if a > 20 {
  3. fmt.Println(">")
  4. } else if a < 20 {
  5. fmt.Println("<")
  6. } else {
  7. fmt.Println("=")
  8. }

if 中的语句

  1. x := "hello go!"
  2. if count := len(x); count > 0 {
  3. fmt.Println("Yes")
  4. }

  1. if _, err := doThing(); err != nil {
  2. fmt.Println("Uh oh")
  3. }

Switch

  1. x := 42.0
  2. switch x {
  3. case 0:
  4. case 1, 2:
  5. fmt.Println("Multiple matches")
  6. case 42: // Don't "fall through".
  7. fmt.Println("reached")
  8. case 43:
  9. fmt.Println("Unreached")
  10. default:
  11. fmt.Println("Optional")
  12. }

参见:Switch

For loop

  1. for i := 0; i <= 10; i++ {
  2. fmt.Println("i: ", i)
  3. }

对于 Range 循环

  1. nums := []int{2, 3, 4}
  2. sum := 0
  3. for _, num := range nums {
  4. sum += num
  5. }
  6. fmt.Println("sum:", sum)

While 循环

  1. i := 1
  2. for i <= 3 {
  3. fmt.Println(i)
  4. i++
  5. }

Continue 关键字

  1. for i := 0; i <= 5; i++ {
  2. if i % 2 == 0 {
  3. continue
  4. }
  5. fmt.Println(i)
  6. }

Break 关键字

  1. for {
  2. fmt.Println("loop")
  3. break
  4. }

Golang 结构和映射

定义

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. type Vertex struct {
  6. X int
  7. Y int
  8. }
  9. func main() {
  10. v := Vertex{1, 2}
  11. v.X = 4
  12. fmt.Println(v.X, v.Y) // => 4 2
  13. }

参见:结构(Structs)

字面量

  1. v := Vertex{X: 1, Y: 2}
  2. // Field names can be omitted
  3. v := Vertex{1, 2}
  4. // Y is implicit
  5. v := Vertex{X: 1}

您还可以输入字段名

映射

  1. m := make(map[string]int)
  2. m["k1"] = 7
  3. m["k2"] = 13
  4. fmt.Println(m) // => map[k1:7 k2:13]
  5. v1 := m["k1"]
  6. fmt.Println(v1) // => 7
  7. fmt.Println(len(m)) // => 2
  8. delete(m, "k2")
  9. fmt.Println(m) // => map[k1:7]
  10. _, prs := m["k2"]
  11. fmt.Println(prs) // => false
  12. n := map[string]int{"foo": 1, "bar": 2}
  13. fmt.Println(n) // => map[bar:2 foo:1]

指向结构的指针

  1. v := &Vertex{1, 2}
  2. v.X = 2

Doing v.X is the same as doing (*v).X, when v is a pointer.

Golang 函数

多个参数

  1. func plus(a int, b int) int {
  2. return a + b
  3. }
  4. func plusPlus(a, b, c int) int {
  5. return a + b + c
  6. }
  7. fmt.Println(plus(1, 2))
  8. fmt.Println(plusPlus(1, 2, 3))

多次返回

  1. func vals() (int, int) {
  2. return 3, 7
  3. }
  4. a, b := vals()
  5. fmt.Println(a) // => 3
  6. fmt.Println(b) // => 7

匿名函数

  1. r1, r2 := func() (string, string) {
  2. x := []string{"hello", "world"}
  3. return x[0], x[1]
  4. }()
  5. // => hello world
  6. fmt.Println(r1, r2)

命名返回

  1. func split(sum int) (x, y int) {
  2. x = sum * 4 / 9
  3. y = sum - x
  4. return
  5. }
  6. x, y := split(17)
  7. fmt.Println(x) // => 7
  8. fmt.Println(y) // => 10

变量函数

  1. func sum(nums ...int) {
  2. fmt.Print(nums, " ")
  3. total := 0
  4. for _, num := range nums {
  5. total += num
  6. }
  7. fmt.Println(total)
  8. }
  9. sum(1, 2) //=> [1 2] 3
  10. sum(1, 2, 3) // => [1 2 3] 6
  11. nums := []int{1, 2, 3, 4}
  12. sum(nums...) // => [1 2 3 4] 10

初始化函数

  1. import --> const --> var --> init()

  1. var num = setNumber()
  2. func setNumber() int {
  3. return 42
  4. }
  5. func init() {
  6. num = 0
  7. }
  8. func main() {
  9. fmt.Println(num) // => 0
  10. }

作为值的函数

  1. func main() {
  2. // 将函数赋给名称
  3. add := func(a, b int) int {
  4. return a + b
  5. }
  6. // 使用名称调用函数
  7. fmt.Println(add(3, 4)) // => 7
  8. }

关闭 1

  1. func scope() func() int{
  2. outer_var := 2
  3. foo := func() int {return outer_var}
  4. return foo
  5. }
  6. // Outpus: 2
  7. fmt.Println(scope()())

关闭 2

  1. func outer() (func() int, int) {
  2. outer_var := 2
  3. inner := func() int {
  4. outer_var += 99
  5. return outer_var
  6. }
  7. inner()
  8. return inner, outer_var
  9. }
  10. inner, val := outer()
  11. fmt.Println(inner()) // => 200
  12. fmt.Println(val) // => 101

Golang 包(Packages)

导入

  1. import "fmt"
  2. import "math/rand"

等同于

  1. import (
  2. "fmt" // 给 fmt.Println
  3. "math/rand" // 给 rand.Intn
  4. )

另见:导入

别名

  1. import r "math/rand"

  1. import (
  2. "fmt"
  3. r "math/rand"
  4. )

  1. r.Intn()

Packages

  1. package main
  2. // 一个内部包只能被另一个包导入
  3. // 那是在以内部目录的父级为根的树内
  4. package internal

另见:内部包

导出名称

  1. // 以大写字母开头
  2. func Hello () {
  3. ···
  4. }

另见:导出的名称

Golang 并发

协程

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. func f(from string) {
  7. for i := 0; i < 3; i++ {
  8. fmt.Println(from, ":", i)
  9. }
  10. }
  11. func main() {
  12. f("direct")
  13. go f("goroutine")
  14. go func(msg string) {
  15. fmt.Println(msg)
  16. }("going")
  17. time.Sleep(time.Second)
  18. fmt.Println("done")
  19. }

参见:Goroutines, Channels

WaitGroup

  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. "time"
  6. )
  7. func w(id int, wg *sync.WaitGroup) {
  8. defer wg.Done()
  9. fmt.Printf("%d starting\n", id)
  10. time.Sleep(time.Second)
  11. fmt.Printf("%d done\n", id)
  12. }
  13. func main() {
  14. var wg sync.WaitGroup
  15. for i := 1; i <= 5; i++ {
  16. wg.Add(1)
  17. go w(i, &wg)
  18. }
  19. wg.Wait()
  20. }

参见:WaitGroup

Closing channels

  1. ch <- 1
  2. ch <- 2
  3. ch <- 3
  4. close(ch) // 关闭频道

  1. // 迭代通道直到关闭
  2. for i := range ch {
  3. ···
  4. }

  1. // Closed if `ok == false`
  2. v, ok := <- ch

参见:范围和关闭

缓冲通道

  1. ch := make(chan int, 2)
  2. ch <- 1
  3. ch <- 2
  4. ch <- 3
  5. // 致命错误:
  6. // 所有 goroutine 都处于休眠状态 - 死锁

参见:缓冲通道

Golang 错误控制

延迟函数

  1. func main() {
  2. defer func() {
  3. fmt.Println("Done")
  4. }()
  5. fmt.Println("Working...")
  6. }

Lambda defer

  1. func main() {
  2. var d = int64(0)
  3. defer func(d *int64) {
  4. fmt.Printf("& %v Unix Sec\n", *d)
  5. }(&d)
  6. fmt.Print("Done ")
  7. d = time.Now().Unix()
  8. }

defer 函数使用当前值d,除非我们使用指针在 main 末尾获取最终值

Defer

  1. func main() {
  2. defer fmt.Println("Done")
  3. fmt.Println("Working...")
  4. }

参见:Defer, panic and recover

Golang 方法(Methods)

接收器

  1. type Vertex struct {
  2. X, Y float64
  3. }
  4. func (v Vertex) Abs() float64 {
  5. return math.Sqrt(v.X * v.X + v.Y * v.Y)
  6. }
  7. v := Vertex{1, 2}
  8. v.Abs()

参见:Methods

Mutation

  1. func (v *Vertex) Scale(f float64) {
  2. v.X = v.X * f
  3. v.Y = v.Y * f
  4. }
  5. v := Vertex{6, 12}
  6. v.Scale(0.5)
  7. // `v` 已更新

参见:指针接收器

Golang 接口(Interfaces)

基本接口(Interfaces)

  1. type Shape interface {
  2. Area() float64
  3. Perimeter() float64
  4. }

结构(Struct)

  1. type Rectangle struct {
  2. Length, Width float64
  3. }

结构 Rectangle 通过实现其所有方法隐式实现接口 Shape

方法(Methods)

  1. func (r Rectangle) Area() float64 {
  2. return r.Length * r.Width
  3. }
  4. func (r Rectangle) Perimeter() float64 {
  5. return 2 * (r.Length + r.Width)
  6. }

Shape 中定义的方法在Rectangle中实现

接口实例

  1. func main() {
  2. var r Shape = Rectangle{Length: 3, Width: 4}
  3. fmt.Printf("Type of r: %T, Area: %v, Perimeter: %v.", r, r.Area(), r.Perimeter())
  4. }

杂项

关键字(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

运算符和标点符号

+ & += &= && == != ( )
- \ -= \ = \ \ < <= [ ]
* ^ *= ^= <- > >= { }
/ << /= <<= ++ = := , ;
% >> %= >>= ! . :
&^ &^=

另见