本文为转载
原出处:http://bbs.laoleng.vip/reference/docs/golang.html 
仓库地址:https://github.com/jaywcjlove/reference 
 
该备忘单提供了帮助您使用 Golang  的基本语法和方法。
入门 hello.go 1 2 3 4 5 package  mainimport  "fmt" func  main ()     fmt.Println("Hello, world!" ) } 
直接运行
1 2 $  go run hello.go Hello, world! 
或者在 Go repl  中尝试一,go 命令参考 
变量 1 2 3 4 5 6 7 var  s1 string s1 = "Learn Go!"  var  b, c int  = 1 , 2 var  d = true _ , e = 10 , 20   
简短声明
1 2 3 s1 := "Learn Go!"          b, c := 1 , 2               d := true                  
参见:基本类型 
函数 1 2 3 4 5 6 7 8 9 10 package  mainimport  "fmt" func  main ()   fmt.Println("Hello world!" )   say("Hello Go!" ) } func  say (message string )   fmt.Println("You said: " , message) } 
参见:函数(Functions) 
注释 if 语句 1 2 3 if  true  {  fmt.Println("Yes!" ) } 
参见:条件控制 
Golang 基本类型 字符串 Strings 1 2 3 4 5 6 7 s1 := "Hello"  + "World"  s2 := `A "raw" string literal  can include line breaks.` fmt.Println(len (s1)) fmt.Println(string (s1[0 :5 ])) 
字符串的类型为 字符串
数字 Numbers 1 2 3 4 5 6 num := 3               num := 3.              num := 3  + 4i          num := byte ('a' )      var  u uint  = 7        var  p float32  = 22.7   
操作符 Operators 1 2 3 4 x := 5  x++ fmt.Println("x + 4 =" , x + 4 ) fmt.Println("x * 4 =" , x * 4 )  
参见:更多操作符 
布尔值 Booleans 1 2 isTrue   := true  isFalse  := false  
操作符 1 2 3 4 5 fmt.Println(true  && true )    fmt.Println(true  && false )   fmt.Println(true  || true )    fmt.Println(true  || false )   fmt.Println(!true )           
参见:更多操作符 
数组 Arrays 1 2 3 4 ┌────┬────┬────┬────┬─────┬─────┐ | 2   | 3   | 5   | 7   | 11   | 13   | └────┴────┴────┴────┴─────┴─────┘   0     1     2     3      4      5  
1 2 3 4 5 6 primes := [...]int {2 , 3 , 5 , 7 , 11 , 13 } fmt.Println(len (primes))  fmt.Println(primes) fmt.Println(primes[0 :3 ]) 
1 2 3 4 5 var  a [2 ]string a[0 ] = "Hello"  a[1 ] = "World"  fmt.Println(a[0 ], a[1 ])  fmt.Println(a)    
2d array 1 2 3 4 5 6 7 8 var  twoDimension [2 ][3 ]int for  i := 0 ; i < 2 ; i++ {    for  j := 0 ; j < 3 ; j++ {         twoDimension[i][j] = i + j     } } fmt.Println("2d: " , twoDimension) 
指针(Pointers) 
1 2 3 4 5 6 7 8 9 10 11 12 13 func  main  ()   b := *getPointer()   fmt.Println("Value is" , b) } func  getPointer  () int ) {  a := 234    return  &a } var  p *int *p = 123        
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 func  main ()      a := 10       a = 20    var  p *int    p = &a             ptr := new (int )          } 
参见:指针(Pointers) 
切片(Slices) 1 2 3 4 5 6 7 8 9 10 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 } 
另见:切片示例 
常量(Constants) 1 2 3 4 const  s string  = "constant" const  Phi = 1.618 const  n = 500000000 const  d = 3e20  / n
常量声明可以使用 iota常量生成器 初始化,它用于
在一个const声明语句中,在第一个声明的常量所在的行,iota被置为0,然后在每一个有常量声明的行加一。 
写在同一行的值是相同的 
 
1 2 3 4 5 6 const  (    a = iota      b     c ) 
类型转换 Go语言中不允许隐式转换,所有类型转换必须显式声明(强制转换),而且转换只能发生在两种相互兼容的类型之间。
1 2 3 4 5 i := 90  f := float64 (i) u := uint (i) s := string (i) 
如何获取int字符串? 1 2 3 4 i := 90  s := strconv.Itoa(i) fmt.Println(s)  
Golang 字符串 字符串函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package  mainimport  (        "fmt"          s "strings"  ) func  main ()              fmt.Println(s.Contains("test" , "e" ))          fmt.Println(len ("hello" ))                fmt.Println("hello" [1 ])              fmt.Println(string ("hello" [1 ])) } 
fmt.Printf 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package  mainimport  (        "fmt"          "os"  ) type  point struct  {        x, y int  } func  main ()         p := point{1 , 2 }         fmt.Printf("%v\n" , p)                                 fmt.Printf("%+v\n" , p)                                fmt.Printf("%#v\n" , p)                                fmt.Printf("%T\n" , p)                                 fmt.Printf("%t\n" , true )                              fmt.Printf("%d\n" , 123 )                               fmt.Printf("%b\n" , 14 )                                fmt.Printf("%c\n" , 33 )                                fmt.Printf("%x\n" , 456 )                               fmt.Printf("%f\n" , 78.9 )                              fmt.Printf("%e\n" , 123400000.0 )                       fmt.Printf("%E\n" , 123400000.0 )                       fmt.Printf("%s\n" , "\"string\"" )                      fmt.Printf("%q\n" , "\"string\"" )                      fmt.Printf("%x\n" , "hex this" )                        fmt.Printf("%p\n" , &p)                                fmt.Printf("|%6d|%6d|\n" , 12 , 345 )                    fmt.Printf("|%6.2f|%6.2f|\n" , 1.2 , 3.45 )              fmt.Printf("|%-6.2f|%-6.2f|\n" , 1.2 , 3.45 )            fmt.Printf("|%6s|%6s|\n" , "foo" , "b" )                 fmt.Printf("|%-6s|%-6s|\n" , "foo" , "b" )               s := fmt.Sprintf("a %s" , "string" )         fmt.Println(s)         fmt.Fprintf(os.Stderr, "an %s\n" , "error" ) } 
另见: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 2 3 4 5 6 7 8 a := 10  if  a > 20  {    fmt.Println(">" ) } else  if  a < 20  {     fmt.Println("<" ) } else  {     fmt.Println("=" ) } 
if 中的语句 1 2 3 4 x := "hello go!"  if  count := len (x); count > 0  {    fmt.Println("Yes" ) } 
1 2 3 if  _, err := doThing(); err != nil  {    fmt.Println("Uh oh" ) } 
Switch 1 2 3 4 5 6 7 8 9 10 11 12 x := 42.0  switch  x {  case  0 :   case  1 , 2 :       fmt.Println("Multiple matches" )   case  42 :          fmt.Println("reached" )   case  43 :       fmt.Println("Unreached" )   default :       fmt.Println("Optional" ) } 
参见:Switch 
For loop 1 2 3 for  i := 0 ; i <= 10 ; i++ {  fmt.Println("i: " , i) } 
对于 Range 循环 1 2 3 4 5 6 nums := []int {2 , 3 , 4 } sum := 0  for  _, num := range  nums {  sum += num } fmt.Println("sum:" , sum) 
For 循环 1 2 3 4 5 i := 1  for  i <= 3  {  fmt.Println(i)   i++ } 
Continue 关键字 1 2 3 4 5 6 for  i := 0 ; i <= 5 ; i++ {  if  i % 2  == 0  {       continue    }   fmt.Println(i) } 
Break 关键字 1 2 3 4 for  {  fmt.Println("loop" )   break  } 
Golang 结构和Maps 定义 
1 2 3 4 5 6 7 8 9 10 11 12 13 package  mainimport  (        "fmt"  ) type  Vertex struct  {        X int          Y int  } func  main ()         v := Vertex{1 , 2 }         v.X = 4          fmt.Println(v.X, v.Y)  } 
参见:结构(Structs) 
字面量 1 2 3 4 5 v := Vertex{X: 1 , Y: 2 } v := Vertex{1 , 2 } v := Vertex{X: 1 } 
您还可以输入字段名
Maps 
1 2 3 4 5 6 7 8 9 10 11 12 13 m := make (map [string ]int ) m["k1" ] = 7  m["k2" ] = 13  fmt.Println(m)  v1 := m["k1" ] fmt.Println(v1)      fmt.Println(len (m))  delete (m, "k2" )fmt.Println(m)  _, prs := m["k2" ] fmt.Println(prs)  n := map [string ]int {"foo" : 1 , "bar" : 2 } fmt.Println(n)  
指向结构的指针 1 2 v := &Vertex{1 , 2 } v.X = 2  
Doing v.X is the same as doing (*v).X, when v is a pointer.
Golang 函数 多个参数 1 2 3 4 5 6 7 8 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 )) 
多返回值 1 2 3 4 5 6 func  vals () int , int ) {  return  3 , 7  } a, b := vals() fmt.Println(a)     fmt.Println(b)     
匿名函数 1 2 3 4 5 6 r1, r2 := func () string , string ) {     x := []string {"hello" , "world" }     return  x[0 ], x[1 ] }() fmt.Println(r1, r2) 
命名返回值 1 2 3 4 5 6 7 8 func  split (sum int ) int ) {  x = sum * 4  / 9    y = sum - x   return  } x, y := split(17 ) fmt.Println(x)    fmt.Println(y)    
可变参数函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 func  sum (nums ...int )   fmt.Print(nums, " " )   total := 0    for  _, num := range  nums {       total += num   }   fmt.Println(total) } sum(1 , 2 )      sum(1 , 2 , 3 )   nums := []int {1 , 2 , 3 , 4 } sum(nums...)   
初始化函数 1 import  --> const  --> var  --> init()
1 2 3 4 5 6 7 8 9 10 var  num = setNumber()func  setNumber () int  {  return  42  } func  init ()   num = 0  } func  main ()   fmt.Println(num)  } 
作为值的函数 1 2 3 4 5 6 7 8 func  main ()      add := func (a, b int ) int  {       return  a + b   }      fmt.Println(add(3 , 4 ))  } 
闭包 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 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) fmt.Println(inner()) 
关闭 1 1 2 3 4 5 6 7 func  scope () func () int {  outer_var := 2    foo := func () int  {return  outer_var}   return  foo } fmt.Println(scope()()) 
Golang 包(Packages) 导入 
1 2 import  "fmt" import  "math/rand" 
等同于 1 2 3 4 import  (  "fmt"            "math/rand"    ) 
另见:导入 
别名 
1 2 3 4 import  (    "fmt"      r "math/rand"  ) 
Packages 1 2 3 4 package  mainpackage  internal
另见:内部包 
导出名称 另见:导出的名称 
Golang 并发 协程 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package  mainimport  (    "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 , Channels 
WaitGroup 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package  mainimport  (    "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 
Closing channels 1 2 3 4 ch <- 1  ch <- 2  ch <- 3  close (ch) 
1 2 3 4 for  i := range  ch {  ··· } 
参见:范围和关闭 
缓冲通道 1 2 3 4 5 6 ch := make (chan  int , 2 ) ch <- 1  ch <- 2  ch <- 3  
参见:缓冲通道 
Golang 错误控制 延迟函数 1 2 3 4 5 6 func  main ()   defer  func ()      fmt.Println("Done" )   }()   fmt.Println("Working..." ) } 
Lambda defer 1 2 3 4 5 6 7 8 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 1 2 3 4 func  main ()   defer  fmt.Println("Done" )   fmt.Println("Working..." ) } 
参见:Defer, panic and recover 
Golang 方法(Methods) 
接收器 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 func  (接收者变量 接收者类型)     函数体 } type  Vertex struct  {  X, Y float64  } func  (v Vertex) float64  {  return  math.Sqrt(v.X * v.X + v.Y * v.Y) } func  (v Vertex) float64  {  v.X += 1    return  v.X } func  (v *Vertex) float64  {  v.X += 1    return  v.X } func  main ()   v := Vertex{1 , 2 }   v.Abs()   v = Vertex{1 , 2 }   fmt.Println(v.valuechange())     fmt.Println(v)                   v = Vertex{1 , 2 }   fmt.Println(v.pointerchange())   fmt.Println(v)                 } 
参见:Methods ,指针接收器 
方法表达式 方法表达式相当于提供一种语法将类型方法调用显式地转换为函数调用,接收者(receiver)必须显式地传递进去。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 func  (t T)     return  t.a } func  (t *T) int ){    t.a = i } type  Data struct {}func  (Data) func  (*Data) var  a Data= struct {}{}Data.TestValue(a)  (*Data).TestPointer (&a)  y : = (&a).TestValue  g : = a.TestPointer  
组合结构的方法集 内嵌字段的访问不需要使用全路径,只要保证命名是唯一的就可以,尽量避免同名。如果外层字段和内层字段有相同的方法,则使用简化模式访问外层方法会覆盖内层的方法。
1 2 3 4 5 6 7 8 9 x : = X{a: 1 }  y : = Y{      X : x ,      b : 2  ,  } z : = z {      Y : y ,      c : 3  , } 
组合结构的方法集有如下规则:
若类型 T 包含匿名字段 S ,则 T 的方法集包含S的方法集 
若类型 T 包含匿名字段 S ,则 T 的方法集包含 S 和 S方法集 
不管类型 T 中嵌入的匿名字段是 S 还是 S , T 方法集总是包含 S 和 *S 方法集 
 
Golang 接口(Interfaces) 
基本接口(Interfaces) 1 2 3 4 type  Shape interface  {  Area() float64    Perimeter() float64  } 
结构(Struct) 1 2 3 type  Rectangle struct  {  Length, Width float64  } 
结构 Rectangle 通过实现其所有方法隐式实现接口 Shape
方法(Methods) 1 2 3 4 5 6 func  (r Rectangle) float64  {  return  r.Length * r.Width } func  (r Rectangle) float64  {  return  2  * (r.Length + r.Width) } 
在 Shape 中定义的方法在Rectangle中实现
接口实例 1 2 3 4 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()) } 
Golang Embed (Go version >= 1.16) 嵌入为string 1 2 3 4 5 6 7 8 9 10 11 12 13 package  mainimport  (    _ "embed"      "fmt"  ) var  version string func  main ()     fmt.Printf("version %q\n" , version) } 
嵌入为[]byte 1 2 3 4 5 6 7 8 9 10 11 12 package  mainimport  (    _ "embed"      "fmt"  ) var  versionByte []byte func  main ()     fmt.Printf("version %q\n" , string (versionByte)) } 
嵌入为embed.FS 1 2 3 4 5 6 var  f embed.FSfunc  main ()   data, _ := f.ReadFile("hello.txt" )   fmt.Println(string (data)) } 
嵌入多个文件 1 2 3 4 5 6 7 8 9 var  f embed.FSfunc  main ()   data, _ := f.ReadFile("hello.txt" )   fmt.Println(string (data))   data, _ = f.ReadFile("hello2.txt" )   fmt.Println(string (data)) } 
嵌入子文件夹下的文件 1 2 3 4 5 6 7 8 var  f embed.FSfunc  main ()   data, _ := f.ReadFile("p/hello.txt" )   fmt.Println(string (data))   data, _ = f.ReadFile("p/hello2.txt" )   fmt.Println(string (data)) } 
同一个文件嵌入为多个变量 1 2 3 4 5 6 7 8 var  s string var  s2 string func  main ()   fmt.Println(s)   fmt.Println(s2) } 
匹配模式 1 2 3 4 5 6 7 8 var  f embed.FSfunc  main ()   data, _ := f.ReadFile("p/.hello.txt" )   fmt.Println(string (data))   data, _ = f.ReadFile("p/q/.hi.txt" )    fmt.Println(string (data)) } 
Golang 泛型 (Go version >= 1.18) 泛型类型 
1 2 3 4 type S[T int|float32|float64 ] []T        ┬  ────────┬────────         ┆          ╰─── 2. 类型约束        ╰────────────── 1. 类型形参 
可以使用类型实参 int 或 string 实例化
1 2 3 4 5 6 type  MyMap[K int |string , V float32  | float64 ] map [K]Vvar  a MyMap[string , float64 ] = map [string ]float64 {    "jack_score" : 9.6 ,     "bob_score" :  8.4 , } 
泛型函数 
任意类型
1 2 3 func  Add [T  any ](a,b T)     return   a+b } 
对类型进行约束
1 2 3 func  Add [T  string  | int  | int8 ](a,b T)     return   a+b } 
类型嵌套
1 2 3 4 5 6 7 type  WowStruct[T int  | float32 , S []T] struct  {    Data     S     MaxValue T     MinValue T } var  ws WowStruct[int , []int ]  
泛型函数中进行类型声明 (go version >= 1.20)
1 2 3 4 func  F [T1  any ]()     type  x struct {}      type  y = x       } 
泛型约束 
通过接口实现
1 2 3 4 5 6 7 type  Addable interface {    type  int , int8 , int16 , int32 , int64 , uint , uint8 , uint16 , uint32 , uint64 , uintptr , float32 , float64 , complex64 , complex128 , string   } func  Add [T  Addable ](a,b T)     return   a+b } 
使用 ~ 符号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 type  Int interface  {    ~int  | ~int8  | ~int16  | ~int32  | ~int64  } type  Uint interface  {    ~uint  | ~uint8  | ~uint16  | ~uint32  } type  Float interface  {    ~float32  | ~float64  } type  Slice[T Int | Uint | Float] []T var  s Slice[int ] type  MyInt int var  s2 Slice[MyInt]  type  MyMyInt MyIntvar  s3 Slice[MyMyInt]  type  MyFloat32 float32   var  s4 Slice[MyFloat32]
使用 ~ 时的限制:
~后面的类型不能为接口
~后面的类型必须为基本类型
 
泛型 Receiver 
定义普通类型支持泛型
1 2 3 4 5 6 7 8 9 type  MySlice[T int  | float32 ] []Tfunc  (s MySlice[T])     var  sum T     for  _, value := range  s {         sum += value     }     return  sum } 
结构体支持泛型
1 2 3 4 5 6 type  A[T int  | float32  | float64 ] struct  {} func  (receiver A[T])     return  a + b } 
泛型接口 
1 2 3 4 5 6 7 8 9 10 type  Uint interface  {     ~uint  | ~uint8  | ~uint16  | ~uint32  | ~uint64  } type  ReadWriter interface  {      ~string  | ~[]rune      Read(p []byte ) (n int , err error )     Write(p []byte ) (n int , err error ) } 
一般接口类型不能用来定义变量,只能用于泛型的类型约束中
杂项 关键字(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
 
运算符和标点符号 
 
 
+&+=&=&&==!=() 
-|-=|=||<<=[] 
*^*=^=<->>={} 
/<</=<<=++=:=,; 
%>>%=>>=--!....: 
&^&^= 
Go 命令 Go 编译器命令 
:- 
– 
 
 
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发现代码中可能的错误 
 
ENV 
Module 
:- 
– 
 
 
go mod init初始化当前文件夹,创建go.mod文件 
 
go mod download下载依赖的module到本地 
 
go mod tidy增加缺少的module,删除无用的module 
 
go mod vendor将依赖复制到vendor下 
 
文件 go.mod 
依赖列表和版本约束 
 
文件 go.sum 
记录 module 文件 hash 值,用于安全校验 
 
另见