分支结构
应用场景
迄今为止,我们写的golang代码都是一条一条语句顺序执行,这种代码结构通常称之为顺序结构。然而仅有顺序结构并不能解决所有的问题,比如我们设计一个游戏,游戏第一关的通关条件是玩家获得1000分,那么在完成本局游戏后,我们要根据玩家得到分数来决定究竟是进入第二关,还是告诉玩家“Game Over”,这里就会产生两个分支,而且这两个分支只有一个会被执行。类似的场景还有很多,我们将这种结构称之为“分支结构”或“选择结构”。给大家一分钟的时间,你应该可以想到至少5个以上这样的例子,赶紧试一试。
if语句的使用
在golang中,要构造分支结构可以使用if
、else if
和else
关键字。所谓关键字就是有特殊含义的单词,像if
和else
就是专门用于构造分支结构的关键字,很显然你不能够使用它作为变量名(事实上,用作其他的标识符也是不可以)。golang 的 if 语句表达式外无需小括号( )
,而大括号 { }
则是必须的下面的例子中演示了如何构造一个分支结构。
/*
token验证
Version: 1.0
Author: 长柳
*/
var token string = "test"
//
if token == "test"{
fmt.Printf("身份验证成功!")
}else {
fmt.Printf("身份验证失败!")
}
当然如果要构造出更多的分支,可以使用if...else if...else...
结构或者嵌套的if...else...
结构,下面的代码演示了如何利用多分支结构实现分段函数求值。
/*
根据分数判断登记
>80:A
70-80:B
60-70:C
<60:D
Version: 1.0
Author: 长柳
*/
score := 85
if score >= 80 {
fmt.Println("Grade: A")
} else if score >= 70 {
fmt.Println("Grade: B")
} else if score >= 60 {
fmt.Println("Grade: C")
} else {
fmt.Println("Grade: D")
}
当然根据实际开发的需要,分支结构是可以嵌套的,例如判断是否通关以后还要根据你获得的宝物或者道具的数量对你的表现给出等级(比如点亮两颗或三颗星星),那么我们就需要在if
的内部构造出一个新的分支结构,同理else if
和else
中也可以再构造新的分支。比如多个变量需要判断的情况
/*
天气情况判断
Version: 1.0
Author: 长柳
*/
temperature := 23.5
humidity := 7
if temperature > 30 {
fmt.Println("晴天")
if humidity > 60 {
fmt.Println("湿热")
} else {
fmt.Println("干燥")
}
} else {
fmt.Println("舒适")
}
说明: if语句在可以在条件表达式前执行一个简单的语句,该语句声明的变量作用域仅在 if 之内,如 if temperature := 23.5;temperature > 30{}。
switch语句的使用
switch
是编写一连串 if - else 语句的简便方法。它运行第一个值等于条件表达式的 case 语句。
Go 的 switch
语句类似于 C、C++、Java、JavaScript 和 PHP 中的,不过 Go 只运行选定的 case,而非之后所有的 case。 实际上,Go 自动提供了在这些语言中每个 case 后面所需的 break 语句。 除非以 fallthrough 语句结束,否则分支会自动终止。 Go 的另一点重要的不同在于 switch 的 case 无需为常量,且取值不必为整数。
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Print("Go runs on ")
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
// freebsd, openbsd,
// plan9, windows...
fmt.Printf("%s.\n", os)
}
}
switch
的 case 语句从上到下顺次执行,直到匹配成功时停止。
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("When's Saturday?")
today := time.Now().Weekday()
switch time.Saturday {
case today + 0:
fmt.Println("Today.")
case today + 1:
fmt.Println("Tomorrow.")
case today + 2:
fmt.Println("In two days.")
default:
fmt.Println("Too far away.")
}
}
没有条件的 switch
同 switch true 一样。
这种形式能将一长串 if-then-else 写得更加清晰。
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("Good morning!")
case t.Hour() < 17:
fmt.Println("Good afternoon.")
default:
fmt.Println("Good evening.")
}
}
练习
练习1:根据年龄判断其年龄段。
参考答案:
package main
import(
"fmt"
)
func main(){
var age int
fmt.Println("请输入年龄")
fmt.Scan(&age)
if age <= 12 {
fmt.Println("儿童")
} else if age <= 18 {
fmt.Println("未成年")
} else if age <= 30 {
fmt.Println("青年")
} else if age <= 50{
fmt.Println("中年")
} else{
fmt.Println("老年")
}
}
练习2:输入三条边长,如果能构成三角形就计算周长和面积。
参考答案:
/*
判断输入的边长能否构成三角形,如果能则计算出三角形的周长和面积
Version: 1.0
Author: 长柳
*/
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("请输入三角形的三条边长(空格分隔):")
inputStr, _ := reader.ReadString('\n')
sidesStr := strings.Fields(inputStr)
var sides []int
for _, str := range sidesStr {
side, _ := strconv.Atoi(str)
sides = append(sides, side)
}
a, b, c := sides[0], sides[1], sides[2]
if canFormTriangle(a, b, c) {
p := (a + b + c) / 2
area := math.Sqrt(p * (p - a) * (p - b) * (p - c))
perimeter := a + b + c
fmt.Printf("输入的边长能构成三角形,其周长为 %.2f,面积为 %.2f。\n", perimeter, area)
} else {
fmt.Println("输入的边长不能构成三角形。")
}
}
func canFormTriangle(a, b, c int) bool {
return a+b > c && a+c > b && b+c > a
}
说明: 上面使用的通过边长计算三角形面积的公式叫做海伦公式。