Go语言的流程控制主要包括条件分支、循环和并发。在本章,我们先来谈谈基本的流程控制语句。具体到本小节,我们将提及if
语句。
if
语句一般会由关键字if
、条件表达式和由花括号包裹的代码块组成。所谓代码块,即是包含了若干表达式和语句的序列。在Go语言中,代码块必须由花括号包裹。另外,这里的条件表达式是指其结果类型是bool
的表达式。一条最简单的if
语句可以是:
if 100 > number {
number += 3
}
这里的标识符number
可以代表一个int
类型的值。这条if
语句的意思是:如果number
的值小于100
,那么就把其值增加3
。我还可以在此之上添加else
分支,就像这样:
if 100 > number {
number += 3
} else {
number -= 2
}
else
分支的含义是,提供在条件不成立(具体到这里是number
的值不小于100
)的情况下需要执行的操作。除此之外,if
语句还支持串联。请看下面的例子:
if 100 > number {
number += 3
} else if 100 < number {
number -= 2
} else {
fmt.Println("OK!")
}
可以看到,上述代码很像是把多条if
语句串接在一起了一样。这样的if
语句用于对多个条件的综合判断。上述语句的意思是,若number
的值小于100
则将其加3
,若number
的值大于100
则将其减2
,若number
的值等于100
则打印OK!
。
注意,我们至此还未对number
变量进行声明。上面的示例也因此不能通过编译。我们当然可以用单独的语句来声明该变量并为它赋值。但是我们也可以把这样的变量赋值直接加入到if
子句中。示例如下:
if number := 4; 100 > number {
number += 3
} else if 100 < number {
number -= 2
} else {
fmt.Println("OK!")
}
这里的number := 4
被叫做if
语句的初始化子句。它应被放置在if
关键字和条件表达式之间,并与前者由空格分隔、与后者由英文分号;
分隔。注意,我们在这里使用了短变量声明语句,即:在声明变量number
的同时为它赋值。这意味着这里的number
被视为一个新的变量。它的作用域仅在这条i
语句所代表的代码块中。也可以说,变量number
对于该if
语句之外的代码来说是不可见的。我们若要在该if
语句以外使用number
变量就会造成编译错误。
另外还要注意,即使我们已经在这条if
语句所代表的代码块之外声明了number
变量,这里的语句number := 4
也是合法的。请看这个例子:
var number int
if number := 4; 100 > number {
number += 3
} else if 100 < number {
number -= 2
} else {
fmt.Println("OK!")
}
这种写法有一个专有名词,叫做:标识符的重声明。实际上,只要对同一个标识符的两次声明各自所在的代码块之间存在包含的关系,就会形成对该标识符的重声明。具体到这里,第一次声明的number
变量所在的是该if
语句的外层代码块,而number := 4
所声明的number
变量所在的是该if
语句的代表代码块。它们之间存在包含关系。因此对number
的重声明就形成了。
这种情况造成的结果就是,if
语句内部对number
的访问和赋值都只会涉及到第二次声明的那个number
变量。这种现象也被叫做标识符的遮蔽。上述代码被执行完毕之后,第二次声明的number
变量的值会是7
,而第一次声明的number
变量的值仍会是0
。