本文适合初学者阅读
- GO精简了流控制语句, 不如python 便捷, 但够用了
if … else …语句
- 条件表达式值必须是布尔类型, 可以省略括号, 且左花括号不能另起一行
func main() {
x := 3
if x > 5 {
println("x大于5了")
} else if x < 5 && x > 0 {
println("x小于5且大于0了")
} else {
println("x 小于0了")
}
}
输出结果为: x小于5且大于0了
- 比例特别的是对初始化语句的支持, 可定义局部变量或执行初始化函数
func main() {
x := 10
if xinit(); x == 0 { // 我的vscode环境里报undined错误
println("x")
} else {
println("z")
}
if a, b := x+1, x+10; a < b { //优先执行这里
println(a)
} else {
println(b)
}
}
局部变量的有效范围包含整个if/else块.
- 尽可能减少代码的嵌套, 让正常逻辑处于相同层次.
switch 语句
package main
func main() {
a, b, c, x := 1, 2, 3, 2
switch x {
case a, b:
println("a | b")
case c:
println("c")
case 4:
println("d")
default:
println("z")
}
}
输出结果:
a|b
- 相邻的空case 不构成多条件匹配
- 不能出现重复的case常量值
- 无须显式执行break语句, case 执行完毕后自动中断.
- 若须贯通后续case(源码顺序), 须执行fallthrough, 但不再匹配后后续条件表达式.
package main
func main() {
switch x := 5; x {
default:
println(x)
case 5:
x += 10
println(x) // 正常执行的结果,x =15
fallthrough // 向下贯通一个
case 6:
x += 30
println(x) // 结果x= 15+30
fallthrough // 再向下贯通一个
case 7:
x += 40
println(x) // // 结果 x= 15+30+40
}
}
结果输出
API server listening at: 127.0.0.1:36911
15
45
85
- 由此看来
fallthrough
只能向下贯通一个case且不执行default
语句块 fallthrough
必须放在case块结尾, 可使用break
语句阻止向下贯通
package main
func main() {
switch x := 5; x {
default:
println(x)
case 5:
x += 10
println(x)
fallthrough
case 6:
x += 30
println(x)
if x >= 45 {
break // 阻止向下贯通或者说是直接跳出执行
}
fallthrough
case 7:
x += 40
println(x)
}
}
结果输出:
API server listening at: 127.0.0.1:42646
15
45
- switch 还被用来替换if语句, 被省略的switch条件表达式默认值为true,继而与case比较表达式结果匹配.
package main
func main() {
switch x := 5; { // 相当于"switch x:=5; true {...}"
case x > 5:
println("x>5")
case x > 0 && x <= 5: // 不能写成"case x>0, x<=5",因为多条件是OR关系
println("b")
default:
println("Z")
}
}
结果输出 : b
for 循环
仅有for 一种循环语句, 常用方式都能支持.
for i := 0; i < 3: i++{ // 初始化表达式支持函数调用或定义局部变量
}
for x < 10 { // 类似"while x < 10 {}" 或 "for ; x<10;{}"
x ++
}
for { // 类似"while true {}" 或"for true {}"
break
}
- 初始化语句仅被执行一次, 条件表达式中如有函数调用, 须确认是否会重复执行.
package main
func count() int {
print("count.")
return 3
}
func main() {
for i, c := 0, count(); i < c; i++ { // 初始化语句,count函数只执行一次
println("a", i)
}
c := 0
for c < count() { // 条件表达式中的count重复执行
println("b", c)
c++
}
}
结果输出
API server listening at: 127.0.0.1:17904
count.a 0
a 1
a 2
count.b 0
count.b 1
count.b 2
count.
- 可以使用
for ... range...
完成数据迭代,支持字符串, 数组, 数组指针, 切片, 字典, 通道类型, 返回索引,键值数据.
package main
func main() {
data := []string{"112", "abc", "xyz"}
for index, value := range data { // 返回索引和数值
println(index, value)
}
}
func main() {
data := []string{"112", "abc", "xyz"}
for _, value := range data { // 只返回数据
println(value)
}
}
func main() {
data := []string{"112", "abc", "xyz"}
for index, _:= range data { // 只返回索引
println(index)
}
}
for range data { //仅迭代不返回. 可用来执行清空channel等操作
}
- 无论普通for循环, 还是range迭代, 其定义的局部变量都会重复使用.
- range会复制目标数据. 受直接影响的是数组, 可改用数组指针或切片类型.
- 建议嵌套循环不要超过2层, 否则会难以维护
goto, contine, break
- 使用goto前,须先定义标签, 标签区分大小写, 且未使用的标签会引发编译错误.
- 不能跳转到其他函数或内层代码块内