版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/guanchunsheng/article/details/79420479
1 if-else
condition条件不需要括号,跟其他语言的if-else没有区别。
格式固定,不可以更改,比如改变{}的位置,是不行的。
if condition1 {
// do something
} else if condition2 {
// do something else
} else {
// catch-all or default
}
一些常见判断
//判断字符串为空
if str == "" {
...
}
if len(str) == 0 {
...
}
//判断当前操作系统类型
if runtime.GOOS == "windows" {
...
}
//判断语句中定义变量,这么做唯一的实际意义是限制val的作用域在if语句块内部
if val := 10; val > max {
// do something
}
//有error返回的函数,判断其结果,出现错误通过return 返回或者os.Exit(1)退出
an, err := strconv.Atoi(orig)
if err != nil {
fmt.Printf("orig %s is not an integer - exiting with error\n", orig)
return
}
//这是一些习惯用法,但是我并不觉得有太大的必要
if value, ok := readData(); ok {
…
}
2 switch
switch var1 {
case val1:
...
case val2, val3:
...
default:
...
}
是不需要break的,自动从某个case跳出。也不需要花括号括起来。
所以小心C语言习惯的连续多个case堆在一起的情况,Go中case后面没有语句,就直接break了。非要这么写的话,加上”fallthrough”
switch i { case 0: fallthrough case 1: f() // 当 i == 0 时函数也会被调用 }
注意:case 1的条件是不做判断的,也就是说,见到fallthrough后,后续的case都不做检查,直接运行case之后的语句块
switch的第二种形式
这个就很方便了,switch没有标的,直接在case后面接条件,相当于很多的if-else。
switch {
case i < 0:
f1()
case i == 0:
f2()
case i > 0:
f3()
}
switch的第三种形式
可以在switch后面接一个初始化语句:
switch a, b := x[i], y[j]; {
case a < b: t = -1
case a == b: t = 0
case a > b: t = 1
}
第三种,我的感觉是跟第二种比,必要性并不是很大,只是限制了局部变量的作用域,局部变量名称的选择更自由而已。
3 for
最传统的方式,注意不要用():
for i := 0; i < 5; i++ {
fmt.Printf("This is the %d iteration\n", i)
}
for i, j := 0, N; i < j; i, j = i+1, j-1 {
...
}
for t, err = p.Token(); err == nil; t, err = p.Token() {
...
}
注意不要在循环体内修改循环变量(计数器),不是好的习惯。
for的第二种形式
这很while:
for i >= 0 {
i = i - 1
fmt.Println(...)
}
//死循环
for {
...
}
for-range
是一个迭代结构,可以参照Python的迭代器。
//ix=index,位置和值在每次迭代中获得
for ix, val := range coll { }
//这里比较厉害的是,可以自动识别str中的ASCII字符和UTF-8规则下的Unicode字符,迭代不会错误的取出部分字符
for pos, char := range str {
fmt.Printf("Character on position %d is: %c \n", pos, char)
}
break, continue
跟其他语言一样,break跳出最内部循环结构,continue直接进入下一次最内部循环。
4 goto和标签
for,switch和select可以配合标签。
LABEL1:
for i := 0; i <= 5; i++ {
for j := 0; j <= 5; j++ {
if j == 4 {
continue LABEL1
}
fmt.Printf("i is: %d, and j is: %d\n", i, j)
}
}
}
----------------------
i is: 0, and j is: 0
i is: 0, and j is: 1
i is: 0, and j is: 2
i is: 0, and j is: 3
i is: 1, and j is: 0
i is: 1, and j is: 1
i is: 1, and j is: 2
i is: 1, and j is: 3
i is: 2, and j is: 0
i is: 2, and j is: 1
i is: 2, and j is: 2
i is: 2, and j is: 3
i is: 3, and j is: 0
i is: 3, and j is: 1
i is: 3, and j is: 2
i is: 3, and j is: 3
i is: 4, and j is: 0
i is: 4, and j is: 1
i is: 4, and j is: 2
i is: 4, and j is: 3
i is: 5, and j is: 0
i is: 5, and j is: 1
i is: 5, and j is: 2
i is: 5, and j is: 3
这里需要注意下,continue出来,并不是重置i,从头开始进入循环,而是进入i的下一次循环,只把j清零。这和直观读代码的感觉稍微有偏差。
除非必要,还是尽量不用吧。