Files
the-way-to-go_ZH_CN/eBook/05.1.md
2013-04-21 19:48:52 -04:00

193 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#5.1 if-else 结构
if 是用于测试某个条件(布尔型或逻辑型)的语句,如果该条件成立,则会执行 if 后由大括号括起来的代码块,否则就忽略该代码块继续执行后续的代码。
if condition {
// do something
}
如果存在第二个分支,则可以在上面代码的基础上添加 else 关键字以及另一代码块这个代码块中的代码只有在条件不满足时才会执行。if 和 else 后的两个代码块是相互独立的分支,只可能执行其中一个。
if condition {
// do something
} else {
// do something
}
如果存在第三个分支,则可以使用下面这种三个独立分支的形式:
if condition1 {
// do something
} else if condition2 {
// do something else
}else {
// catch-all or default
}
else-if 分支的数量是没有限制的,但是为了代码的可读性,还是不要在 if 后面加入太多的 else-if 结构。如果你必须使用这种形式,则把尽可能先满足的条件放在前面。
即使当代码块之间只有一条语句时,大括号也不可被省略(尽管有些人并不赞成,但这还是符合了软件工程原则的主流做法)。
关键字 if 和 else 之后的左大括号 `{` 必须和关键字在同一行,如果你使用了 else-if 结构,则前段代码块的右大括号必须和 else-if 关键字在同一行。这两条规则都是被编译器强制规定的。
非法的Go代码:
if x{
}
else { // 无效的
}
要注意的是,在你使用 `gofmt` 格式化代码之后,每个分支内的代码都会缩进 4 个或 8 个空格,或者是 1 个 tab并且右大括号与对应的 if 关键字垂直对齐。
CHECK
有时,条件两边的括号()是可以省略的,当条件比较复杂时,使用括号()可以让代码更清楚.条件可以是复合条件,使用逻辑操作符&&, || 和!,通过使用()可以强制优先级,提高代码可读性.
一种可能的应用是测试变量值,在不同的情况下,执行不同的语句,但是5.3章节讲到的switch语句更适合这种场景.
<pre>
Listing 5.1 - booleans.go:
package main
import “fmt”
func main() {
bool1 := true
if bool1 {
fmt.Printf(“The value is true\n”)
} else {
fmt.Printf(“The value is false\n”)
}
}
// Output: The value is true
</pre>
注意 不需要判断if bool1 == true,因为bool1已经是一个boolean类型的值.
当测试true和有利条件时,几乎都正常,但是有可能需要判断反向用!(not): if !bool1 或者 if !(condition). 在最后的列子中,条件两边的括号()常常是必须的,例如: if !(var1 == var2).
如果if结构内有break,continue,goto或return语句时,可以省略else子句.(见5.2章节).条件是否成立,返回不同的值x和y时:
<pre>
if condition {
return x
}
return y
</pre>
标记: 不要同时在if else的两个分支里都使用return,将会编译报错:"function ends without a return statement"(这是一个编译BUG)
一些有用的例子:
(1)判断一个字符串是否为空:
<pre>
if str == "" { ... }
or
if len(str) == 0 {...}
</pre>
(2)判断运行Go程序的操作系统类型
可以通过运行时常量来判断.GOOS(见2.2)
<pre>
if runtime.GOOS == "windows" {
...
} else { // Unix - like
...
}
</pre>
init()方法是适合执行这段代码的地方.这是一个代码片段, 改变输入结束的提示.
<pre>
var prompt = "Enter a digit, e.g. 3 "+ "or %s to quit."
func init() {
if runtime.GOOS == "windows" {
prompt = fmt.Sprintf(prompt, "Ctrl+Z, Enter")
} else { //Unix-like
prompt = fmt.Sprintf(prompt, "Ctrl+D")
}
}
</pre>
(3)一个Abs()方法,返回一个整型数字的绝对值:
<pre>
func Abs(x int) int {
if x < 0 {
return -x
}
return x
}
</pre>
(4) 一个比较两个整型数字大小的方法:
<pre>
func isGreater(x, y int) bool {
if x > y {
return true
}
return false
}
</pre>
在第四种情况,if可以以一个初始化语句开始(如给一个变量赋值).固定的格式(在初始化语句后必须加上分号;):
<pre>
if initialization; condition {
// do something
}
</pre>
例如:
<pre>
val := 10
if val > max {
// do something
}
</pre>
你可以这样写:
<pre>
if val := 10; val > max {
// do something
}
</pre>
但是注意,简洁的初始化变量 := 方式声明的变量只存在与if结构中.(变量范围只在if{}的大括号之间,如果有if结构有else子句时,在else子句中变量也存在):如果变量在if结构之前就已经存在,那么在if结构中,该变量原来的值会被隐藏.一个简单的解决办法就是不在初始化中使用:=(见5.2的例3 怎么使用)
Listing 5.2-ifelse.go:
<pre>
package main
import "fmt"
func main() {
var first int = 10
var cond int
if first <= 0 {
fmt.Printf("first is less than or equal to 0\n")
} else if first > 0 && first < 5 {
fmt.Printf("first is between 0 and 5\n")
} else {
fmt.Printf("first is 5 or greater\n")
}
if cond = 5; cond > 10 {
fmt.Printf("cond is greater than 10\n")
} else {
fmt.Printf("cond is not greater than 10\n")
}
}
Output: first is 5 or greater cond is not greater than 10
</pre>
The following code-snippet shows how the result of a function process( ) can be retrieved in the if,
and action taken according to the value:
<pre>
if value := process(data); value > max {
...
if value := process(data); value > max {
...
}
</pre>
##链接
- [目录](directory.md)
- 上一节:[控制结构](05.0.md)
- 下一节: [TODO](05.2.md)