翻译: Effective Go (3)
控制结构
Go的控制结构和C类似,但还是有很多重点不一样。Go没有do或者while循环,只有一个更通用的for循环;switch相比也更灵活;if和switch可以像for循环一样,接受一个初始化语句;break和continue语句带有一个可选标签标志需要break或者continue的内容;新增了一个新的控制结构,包括一个类型选择和多路通信复用器——select;控制结构的语法相比也有细微的差别:没有小括号,并且主体必须用大括号分隔。
If
在Go中,一个简单的if应是这样:
强制使用大括号鼓励将简单的if语句分成多行编写,这是一个很好的风格,尤其当主体语句中包括一个控制语句(例如return或break)。
由于if和switch接受一个初始化语句,因此通常可以用来声明局部变量。
在Go的库中,你会发现if语句当不会执行下一条语句时——即if主体结束于break,continue,goto或return时,将会省略不必要的else。
上面的就是一个常见情况的示例,这种情况下,代码必须防范一系列错误情况,如果控制流继续运行到底,说明错误已经被全部处理。由于错误的情况通常以return返回,所以自然不需要else语句了。
重复声明和重新赋值
上面的示例演示了 := 短变量声明的一些细节。调用os.Open的声明为:
f, err := os.Open(name)
这个语句声明了两个变量,f和err。几行后,f.Stat的调用:
d, err := f.Stat()
似乎又声明了d和err两个变量。但是请注意,虽然err出现在了两个地方,但是这样的重复是合法的:err在第一个语句中声明,第二个语句只是重新赋值而已。也就是说,调用f.Stat只是使用了先前声明的,已存在的err变量,重新进行了赋值。
在 := 声明中,可以出现已经声明的变量v,条件是:
本声明和v的声明在同一作用域。(如果v在另一个作用域声明,那么本次声明会创建一个新变量。注)
两次声明的类型相同
本次的声明至少创建了一个新的变量
这个特性纯粹是实用主义,你会发现在if-else长链,经常看见只要简单的使用一个err变量。
注:值得注意的是,Go的函数入参、返回值的作用域和函数体相同,即使它们按词法出现在包围主体的括号之外。
For
Go的for循环和C不完全一样。它统一了for和while循环,并且没有do-while循环。一共有三种for循环,只有一种有分号。
短变量声明让索引变量声明变得轻松:
如果要循环数组(array),切片(slice),字符串(string),映射(map),或读取一个管道(channel),range可以更高效:
如果在range中只需要第一项,键(key)或者索引(index),只需要删除第二项:
如果在range中只需要第二项,则需要使用空白标识符(下划线)丢弃第一项:
空白标示符有很多用法,可见下一章.
至于string,range做了更多的工作。通过解析UTF-8来分解单个Unicode码点,错误的编码会占用一个字节,并产生替换rune U+FFFD。(内建类型rune用来表示一个Unicode码点。有关详细信息可以参考语言规范)。下面的循环:
会输出:
最后,Go没有逗号运算符,而 ++ 和 --为语句而不是表达式。因此,如果想在for循环中使用多个变量,你应该使用平行赋值。(尽管这排除了++和--)
Switch
Go的switch比C更为通用。其表达式不需要是常量或者整数,case会从上到下执行,直到有匹配,如果switch后面没有表达式,则匹配true,因此,可以将if-else-if-else长链写成一个switch,这也更符合Go的习惯。
switch不会自动执行所有case,相同条件的case可以通过逗号放在一起:
break语句可以用来提前结束switch,但不像其他类C语言中那么常用。有时候不仅需要中断switch,还需要中断外层的循环,在Go中就可以通过在循环前放置一个标签,然后break这个标签来完成。下面展示了这两种用法:
当然,continue语句也可以接受一个可选的标签,不过仅用于循环。
本节的结束示例,是一个使用两个switch语句的字节切片(byte slices)的比较程序:
类型选择(Type switch)
switch也可以用于确认接口的动态类型。类型选择使用小括号中内建的关键字type进行类型断言。若switch后面的表达式声明了变量,则该变量应具备某个子句中相应的类型。这种情况下,通常会重用变量名,但实际上会声明一个具有相同名称但类型不同的新变量。
版权声明: 本文为 InfoQ 作者【申屠鹏会】的原创文章。
原文链接:【http://xie.infoq.cn/article/b969b91d08d6d8ae928bc8e20】。文章转载请联系作者。
评论