if语句
语法
IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] .
特点
if后面的条件判断表达式不需要小括号括起来。左大括号{必须放在和if/else if同行的行尾。if后面可以带一个简单语句,该语句可以声明新的变量并初始化或给已有变量赋值,新声明的变量仅在该if分支、else if分支以及else分支可见。该简单语句和后面的条件判断表达式用“;”分隔。else if和else必须与上一个if分支的右大括号}在同一行。Go语言没有条件运算符(也称三目运算符,a>b?a:b)。此时只能用if else来替换。
最佳实践
尽量减少if条件表达式的复杂度,以提高代码可读性。如果条件表达式逻辑较为复杂,可以将判断逻辑放到一个函数里,该函数返回判断结果。尽可能的减少if语句的嵌套层次,嵌套层次越多,代码可读性就越差,可维护性也越低。可以在if分支内使用return语句来提前结束函数执行,减少if嵌套层次,使代码结构变得扁平。
优化前代码示例:
优化后代码示例:
switch语句
语法
SwitchStmt = ExprSwitchStmt | TypeSwitchStmt .ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" .ExprCaseClause = ExprSwitchCase ":" StatementList .ExprSwitchCase = "case" ExpressionList | "default" .
特点
switch语句会根据传入的参数检测并执行符合条件的case分支。和if语句一样,switch后面也可以带一个简单的初始化或赋值语句,语句中新声明的变量该在switch语块内可见。switch条件表达式的值可以是任意支持相等比较运算的类型变量。switch支持default分支,当所有case分支都未被匹配到,则执行default分支,default分支出现的位置和顺序不影响case的分支条件判断。switch后面的表达式是可选的。如果switch后面没条件判断表达式,则每个case子句的表达必须是条件判断表达式,而不是一个值。可以通过fallthough语句强制执行下一个case分支,无论该case分支是否符合条件。
for语句
与其它语言不同,Go语言只支持一个循环结构语法,即for语句。不像其它语言除for外有do, while以及foreach等丰富的循环结构语法。
Go语言中for语句存在多种形式
形式一
ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .InitStmt = SimpleStmt .PostStmt = SimpleStmt .
这种形式与其它语言的for循环结构相同。
形式二
ForStmt = "for" [ Condition | ForClause | RangeClause ] Block .Condition = Expression .
这种形式与其它语言的while(expr)循环结构相同。
形式三
RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression .
这种形式与其它语言的foreach结构相同。
break关键字
可以使用break关键字强制跳出for、switch、select语句的执行。
在有多个嵌套层的for、switch、select结构中,break跳出当前所在的嵌套层,也可以使用break Label跳出到外层。
continue关键字
continue关键字用于跳出for循环的本次迭代,直接跳到下一次迭代的PostStmt语句处开始执行。
和break关键字一样,在有多个嵌套层的for循环结构中,continue跳到当前所在的for循环层,也可以使用continue Label跳出到外层。
标签和跳转
标签语法
Label: Statement
只能在函数内部声明Label
goto
语法
GotoStmt = "goto" Label .
特点
goto语句只能在函数内部跳转。goto语句不能跳过内部变量声明语句。goto语句只能跳到同级作用域或者上层作用域,不能跳到内部作用域内。