基础知识 常量 预声明标识符 iota 用在常量声明中,其初始值为 0。一组多个常量同时声明时其值逐行增加,iota 可以看做是自增枚举变量,专门用来初始化常量。
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 const ( c0 = iota c1 = iota c3 = iota ) const ( c0 = iota c1 c2 ) const ( a == 1 << iota b == 1 << iota c == 1 << iota ) const ( u = iota * 42 v = iota * 42 w = iota * 42 ) const x = iota const y = iota
布尔类型 1 2 3 4 5 6 7 8 9 10 11 ok := false var a bool a = 1 for ; true ;{ ... } var b bool
整型 byte 是 uint8 的别名,不同类型的整型必须进行强制类型转换。
1 2 3 4 5 var a int = 1 var b int32 = 2 b = a var a int = (1 +2 )*3 var b int = 1000 >> 2
复数 复数 complex64 其实是由两个 float32 浮点数表示,一个为实部、一个为虚部,
1 2 3 4 5 var value1 complex64 = 3.1 +5i value2 := 3.1 +5i var v = complex (2.1 ,3 )a = real (v) b = image(v)
字符串 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 var a = "hello,world" b := a[0 ] a[1 ] = 'a' b := []byte (a) c := a[0 :4 ] d := a[1 :] e := []byte (a) f := []rune (a) g = a + b len (a)for i:=0 ;i< len (d);i++{ fmt.Println(d[i]) } for i, v:= range d{ fmt.Println(i,v) }
数组
1 2 3 4 5 var arr [2 ]int a := [3 ]int {1 , 2 , 3 } b := [...]int {1 , 2 , 3 } c := [3 ]int {1 :1 , 2 :3 } d := [...]int {1 :1 , 2 :3 }
相关操作:
1 2 3 4 5 a := [...]int {1 , 2 , 3 } b := a[0 ] for i,v := range a { ... }
1 2 3 4 5 a := [...]int {1 , 2 , 3 } alength := len (a) for i := 0 ; i < alength ; i++ { ... }
切片
1 2 3 4 var a = [...]int {0 , 1 , 2 , 3 , 4 , 5 , 6 }s1 := a[0 :4 ] s2 := b[:4 ] s3 := c[2 :]
由 make 创建的切片各个元素被默认初始化成切片元素类型的零值。
1 2 3 4 a := make ([]int , 10 ) b := make ([]int ,10 ,15 )
切片支持的操作
len() 返回切片长度
cap() 返回切片底层数组容量
append() 对切片追加元素
copy() 复制切片
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 a := [...]int {1 , 2 , 3 , 4 , 5 , 6 } b := make ([]int , 2 , 4 ) c := a[0 :3 ] len (b) cap (b) b = append (b, 1 ) len (b) cap (b) b = append (b, c...) len (b) cap (b) d := make ([]int , 2 , 3 ) copy (d, c) len (d) cap (d)
1 2 3 str := "hello,world" a := []byte (str) b := []rune (str)
字典(map) 定义类型: map[k]T
其中 k 为索引类型,可以是任意可以进行比较的类型;T是值类型
1 ma := map [string ]int {"a" : 1 , "b" : 2 }
1 2 mp1 := make (map [int ]string , 10 ) mp1[1 ] = "tom"
1 2 3 4 5 6 7 8 9 10 11 mp := make (map [int ]string ) mp[1 ] = "tom" mp[1 ] = "pony" mp[2 ] = "jaky" mp[3 ] = "andes" delete (mp, 3 )for k,v := range mp{ fmt.Println("key=" , k, "value=" , v) }
注意:
1 2 3 4 5 6 7 8 9 10 11 12 13 type User struct { name string age int } ma := make (map [int ]User) andes := User { name: "anedes" , age: 18 , } ma[1 ] = andes andes.age = 19 ma[1 ] = andes
Struct
1 2 3 struct { FeildName FeildType }
1 2 3 type TypeName struct { FeildName FeildType }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 type Person struct { Name string Age int } type Student struct { *Person Number int } a := Person{"Tom" ,21 } p := &Person { Name: "tata" , Age: 12 , } s : Student { Person: p, Number: 110 , }
if 语句最佳实践 代码改写前:
1 2 3 4 5 6 if err, file := os.Open("xxx" ); err == nil { defer file.Close } else { return nil , err }
改写后:
1 2 3 4 5 6 err, file := os.Open("xxxx" ) if err != nil { return nil , err } defer file.Close()
Switch 语句 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 switch i := "y" ; i { case "y" , "Y" : fmt.Println("yes" ) fallthrough case "n" , "N" : fmt.Println("no" ) } score := 85 grade := ' ' switch { case score >= 90 : grade = 'A' case score >= 80 : grade = 'B' case score >= 70 : grade = 'C' case score >= 60 : grade = 'D' default : grade = 'F' } fmt.Printf("grade=%c\n" , grade)
for 语句
1 2 3 for init; condition; post { ... }
for 的其他用法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 for key, value := range map {}for key := range map {}for index, value := range arry{}for index := range arry{}for _,value := range arry{}for index, value := range slice{}for index := range slice{}for _,value := range slice{}for value := range channel{}
标签和跳转 标签 标签用于 goto、break、continue 语句的跳转,标签的语法是:
goto
goto 语句只能在函数内部跳转
goto 不能跳过内部变量声明语句,这些变量在 goto 语句的标签语句处又是可见的。
goto 语句只能跳到同级作用域或者上层作用域内,不能跳到内部作用域内。例如:
1 2 3 4 5 6 7 8 9 10 if n%2 == 1 { go L1 } for n > 0 { f() n-- L1: f() n-- }
break break 用于函数内 for、switch、select语句的执行,有2种使用格式:
单独使用用于跳出break当前所在的语句
和标签一起使用,用于跳出标签所标识的 for、switch、select语句的执行,可用于跳出多重循环,但标签和 break必须在同一个函数内。
1 2 3 4 5 6 7 8 9 10 11 12 13 L1: for i := 0 ; ; i++ { for j := 0 ; ; j++ { if i >= 5 { break L1 } if j > 10 { break } } }
continue 用于跳出 for 循环本次迭代,跳到 for 循环的下一次迭代的 post 语句处执行,也有两种使用格式
1 2 3 4 5 6 7 8 9 10 11 12 13 L1: for i := 0 ; ; i++ { for j := 0 ; ; j++ { if i >= 5 { continue L1 } if j > 10 { continue } } }