本文已参与「开源摘星计划」,欢迎正在阅读的你加入。
上文介绍了go的一些基础声明,比如函数、变量、常量等等。使用这些我们可以写一些简单的加减乘除算法,如果需要实现更加复杂的逻辑,就需要控制流来帮助。
下面我们来看go的控制流语法,包括循环、条件、switch/case、延迟等。
package main
import "fmt"
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
}
这里利用循环for实现了0到10的累加,跟c语言看起来很类似,没错,go结合了多种语言的特点,然后做了简化,使得看起来、写起来,都十分的优雅。
func main() {
sum := 1
// for ; sum < 1000; {
for sum < 1000 {
sum += sum
}
fmt.Println(sum)
}
可以省略for循环的初始化和变化语句。当然,也可以直接只写for的条件语句,这时候的for循环就相当于while循环,go为了简化,就把这两种合并了,省事。
func main() {
for {
// do what you want do
// continue
// break
}
}
有小朋友会好奇,那没有while怎么实现一个死循环呢?如上,直接for关键字,花括号里做你想做的就好了。
当然,如果你想跳过某次循环,可以使用continue。如果你想中断循环,那么就使用break。
func main() {
sum := 1
for i := 0; i < 10; i++ {
if v := i % 2; v == 1 {
sum += i
} else if i == 10 {
break
} else {
continue
}
}
fmt.Println(sum)
}
通过if语句,这里实现了计算10以内奇数之和的算法。这里写了些奇怪的逻辑,目的是为了展示else、else if和break、continue的用法。
当你需要写很多else if的逻辑时,使用switch关键字会让代码逻辑更加清晰、直观。
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("早上好!")
case t.Hour() < 17:
fmt.Println("下午好!")
default:
fmt.Println("晚上好!")
}
}
当然,switch后面也可以接表达式。
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:
fmt.Printf("%s.\n", os)
}
}
最后介绍一个go语言比较特殊的关键字——defer。直接翻译是“延后”的意思。我们先来看一段代码。
package main
import "fmt"
func main() {
fmt.Println("counting")
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}
fmt.Println("done")
}
这里首先执行打印counting,这里没问题。接着进入循环,defer关键词会把打印i的命令压入“栈”(stack)中。然后打印done,函数执行结束。这时,会从前面所说的“栈”中获取命令来执行。学习过“栈”这个数据结构的同学知道,“栈”具有“先入后出”的特点。所以上面代码的执行结果是:
counting
done
9
8
7
6
5
4
3
2
1
0
好了,到这里,已经介绍完了go语言主要的控制流语法。
知道了声明和控制相关的语法,让我们已经可以实现较复杂的算法了。但是,光有高明的算法还是不够的,还需要适合的数据结构来帮助我们更好的实现逻辑。
下一节,我们就讲下go语言提供哪些内置的数据结构。