1、if-else
ifx>0{ ← { is mandatory
return y
} else {
return x
}
if true && true {
println("true")
}
if ! false {
println("true")
}
下面的语法在 Go 中是非法的:
if err != nil
{ ← 必须同 if 在同一行
}
注:没有 do 或者 while 循环,只 有 for。
你会发现当一个 if 语句不会进入下一个语句流程 – 也就是说,语
句体结束于 break,continue,goto 或者 return – 不必要的 else 会被省略。
2、goto
Go 有 goto 语句——明智的使用它。用 goto 跳转到一定是当前函数内定义的标 签。例如假设这样一个循环:
func myfunc() { i := 0
Here: ← 这行的第一个词,以分号结束作为标签
println(i)
i++
goto Here ← 跳转
}
注:标签名是大小写敏感的。
3、for
Go 的 for 循环有三种形式,只有其中的一种使用分号。
for init; condition; post { } ← 和 C 的 for 一样
for condition { } ← 和 while 一样
for { } ←和C 的for(;;) 一样(死循环)
短声明使得在循环中声明一个序号变量更加容易。
sum := 0
for i := 0; i < 10; i++ {
sum +=i ←sum=sum+i 的简化写法
} ← i 实例在循环结束会消失
最后,由于 Go 没有逗号表达式,而 ++ 和 – 是语句而不是表达式,
如果你想 在 for 中执行多个变量,应当使用 平行赋值。
// Reverse a
for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 { ← 平行赋值
a[i], a[j] = a[j], a[i] ← 这里也是
}
4、break 和 continue
利用 break 可以提前退出循环,break 终止当前的循环。
for i := 0; i < 10; i++ {
if i > 5 {
break ← 终止这个循环,只打印 0 到 5
}
println(i)
}
循环嵌套循环时,可以在 break 后指定标签。用标签决定哪个循环被终止:
J: forj:=0;j<5;j++{
for i := 0; i < 10; i++ {
if i > 5 {
break J ← 现在终止的是 j 循环,而不是 i 的那个
}
println(i)
}
}
利用 continue 让循环进入下一个迭代,而略过剩下的所有代码。下面循环打印 了 0 到 5。
for i := 0; i < 10; i++ {
if i > 5 {
continue ← 跳过循环中所有的代码
}
println(i)
}
5、range
保留字 range 可用于循环。它可以在 slice、array、string、map 和 channel。
range 是个迭代器,当被调用的时候,从它循环的内容中返回一个键值对。
基于不同的内容,range 返回不同的东西。
当对 slice 或者 array 做循环时,range 返回序号作为键,这个序号对应的内容作为值。
考虑这个代码:
list := []string{"a", "b", "c", "d", "e", "f"}
for k, v := range list {
// 对k 和v 做想做的事情
}
创建一个字符串的 slice。
用 range 对其进行循环。每一个迭代,range 将返回 int 类型的序号,string 类型的值,以 0 和 “a” 开始。
k的值为0...5,而v在循环从“a”...“f”。
也可以在字符串上直接使用 range。这样字符串被打散成独立的 Unicode 字符
并且起始位按照 UTF-8 解析。循环:
for pos, char := range "aΦx" {
fmt.Printf("character '%c' starts at byte position %d
", char, pos)
}
打印
character 'a' starts at byte position 0
character 'Φ' starts at byte position 1
character 'x' starts at byte position 3 ← Φ took 2 bytes
6、switch
Go 的 switch 非常灵活。表达式不必是常量或整数,执行的过程从上至下,
直到找到匹配项,而如果 switch 没有表达式,它会匹配 true 。
这产生一种可能: 使用 switch 编写 if-else-if-else 判断序列。
func unhex(c byte) byte {
switch {
case '0' <= c && c <= '9': return c - '0'
case 'a' <= c && c <= 'f': return c - 'a' + 10
case 'A' <= c && c <= 'F': return c - 'A' + 10
}
return 0
}
它不会匹配失败后自动向下尝试,但是可以使用 fallthrough 使其这样做。
没有fallthrough:
switch i {
case 0: // 空的 case 体
case 1: // 当i==0 时,f 不会被调用!
f()
}
而这样:
switch i {
case 0: fallthrough
case 1:
f() // 当i==0 时,f 会被调用!
}
用 default 可以指定当其他所有分支都不匹配的时候的行为。
switch i {
case 0:
case 1:
f()
default:
g() // 当i 不等于0 或1 时调用
}
分支可以使用逗号分隔的列表。
func shouldEscape(c byte) bool {
switch c {
case ' ', '?', '&', '=', '#', '+': // , as "or"
return true
}
return false
}
这里有一个使用两个 switch 对字节数组进行比较的例子:
// 比较返回两个字节数组字典数序先后的整数。
// 如果a==b 返回0,如果a<b 返回-1,而如果a>b 返回+1
func Compare(a, b []byte) int {
for i := 0; i < len(a) && i < len(b); i++ {
switch {
case a[i] > b[i]:
return 1
case a[i] < b[i]:
return -1
}
}
// 长度不同,则不相等
switch {
case len(a) < len(b):
return -1
case len(a) > len(b):
return 1
}
return 0 // 字符串相等
}