// var a struct {x int} = {100} // syntax error// var b []int = { 1, 2, 3} // syntax error// c := struct {x int; y string} // syntax error: unexpected semicolon or newline// {// }var a =struct{ x int}{100}var b =[]int{1,2,3}
3.2 初始化值以”,“分隔,可以分多行,但最后一页必须以”,“或者”}“结尾
a :=[]int{1,2// Error: need trailing comma before newline in composite literal}
a :=[]int{1,2,// ok}
b :=[]int{1,2}// ok
4 控制流
4.1 if语句
go中if很特别
可省略条件表达式括号。
支持初始化语句,可定义代码块局部变量。
代码块左大括号必须在条件表达式尾部。
x :=0// if x > 10 // Error: missing condition in if statement// {// }if n :="abc"; x >0{// 初始化语句未必就是定义变量,比如 println("init") 也是可以的。println(n[2])}elseif x <0{// 注意 else if 和 else 左大括号位置。println(n[1])}else{println(n[0])}
不支持三元操作符 ”a>b?a:b“
4.2 For
支持三种循环方式,包括类型while语法。
s :="abc"for i, n :=0,len(s); i < n; i++{// 常见的 for 循环,支持初始化语句。println(s[i])}
n :=len(s)for n >0{// 替代 while (n > 0) {}println(s[n])// 替代 for (; n > 0;) {}
n--}for{// 替代 while (true) {}//传说中的死循环println(s)// 替代 for (;;) {}}
4.3 Range
4.3.1 类似于迭代器操作,返回 (索引, 值) 或 (键, 值)。
1st value 2nd value
------------------+-------------------+------------------+-------------------string index s[index] unicode,rune
array/slice index s[index]map key m[key]
channel element
4.3.2 可忽略不想要的返回值,或用 “_” 这个特殊变量。
s :="abc"for i :=range s {// 忽略 2nd value,支持 string/array/slice/map。println(s[i])}for_, c :=range s {// 忽略 index。println(c)}forrange s {// 忽略全部返回值,仅迭代。...}
m :=map[string]int{"a":1,"b":2}for k, v :=range m {// 返回 (key, value)。println(k, v)}
4.3.3 range会赋值对象。
a :=[3]int{0,1,2}for i, v :=range a {// index、value 都是从复制品中取出。if i ==0{// 在修改前,我们先修改原数组。
a[1], a[2]=999,999
fmt.Println(a)// 确认修改有效,输出 [0, 999, 999]。}
a[i]= v +100// 使用复制品中取出的 value 修改原数组。}
fmt.Println(a)// 输出 [100, 101, 102]。
建议修改成引用类型,其底层数组不会被复制。
package main
import"fmt"funcmain(){
s :=[]int{1,2,3,4,5}for i, v :=range s {// 复制 struct slice { pointer, len, cap }。if i ==0{
s = s[:3]// 对 slice 的修改,不会影响 range。
s[2]=100// 对底层数据的修改。}
fmt.Println(i, v)}}
另外两种引用类型 map、channel 是指针包装,而不像 slice 是 struct。
4.4 Switch
4.4.1 分支表达式可以时任意类型,不限制于常量。可省略break,默认自动终止。
x :=[]int{1,2,3}
i :=2switch i {case x[1]:println("a")case1,3:println("b")default:println("c")}//输出
a
4.4.2 如果需要继续下一分支,可使用fallthrought,但不再判断条件。
x :=10switch x {case10:println("a")fallthroughcase0:println("b")}//输出
a
b
4.4.3 省略条件表达式,可当if…else if…else 使用。
switch{case x[1]>0:println("a")case x[1]<0:println("b")default:println("c")}switch i := x[2];{// 带初始化语句case i >0:println("a")case i <0:println("b")default:println("c")}
funcmain(){var i intfor{
fmt.Println(i)
i++if i >2{goto BREAK
}}
BREAK:
fmt.Println("break")
EXIT:// Error: label EXIT defined and not used}
4.4.5 配合标签,break 和 continue 可在多级嵌套循环中跳出。
package main
import"fmt"funcmain(){
L1:for x :=0; x <3; x++{
L2:for y :=0; y <5; y++{if y >2{continue L2
}if x >1{break L1
}
fmt.Print(x,":", y," ")}
fmt.Println()}}
4.4.6 break 可用于 for、switch、select,而 continue 仅能用于 for 循环。
x :=100switch{case x >=0:if x ==0{break}println(x)}