循环语句
Go 只有一种循环结构——for
循环。
基本的 for 循环除了没有了 ( )
之外(甚至强制不能使用它们),看起来跟 C 或者 Java 中做的一样,而 { }
是必须的。
func main() {
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
fmt.Println(sum)
}
// 结果:45
跟 C 或者 Java 中一样,可以让前置、后置语句为空。
func main() {
sum := 1
for sum < 1000 {
sum += sum
}
fmt.Println(sum)
}
// 结果:1024
如果省略了循环条件,循环就不会结束,因此可以用更简洁地形式表达死循环。
func main() {
for {
}
}
条件语句 if
if 语句除了没有了 ( )
之外(甚至强制不能使用它们),看起来跟 C 或者 Java 中的一样,注意 { }
是必须的。
func sex(man bool) string {
if man {
return fmt.Sprint("you are a man")
}
return fmt.Sprint("you are a woman")
}
func main() {
man := true
sex(man)
fmt.Println(sex(man))
}
// 结果:you are a man
if 的便捷语句
跟 for 一样,if
语句可以在条件之前执行一个简单的语句。
由这个语句定义的变量的作用域仅在 if 范围之内。
func pow(x, n, lim float64) float64 {
// pow 为计算 x 的 n 次幂
if v := math.Pow(x, n); v < lim {
return v
}
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
// 结果:9 20
if 和 else
在 if 的便捷语句定义的变量同样可以在任何对应的 else 块中使用。
func pow(x, n, lim float64) float64 {
if v := math.Pow(x, n); v < lim {
return v
} else {
fmt.Printf("%g >= %g\n", v, lim)
}
// 这里开始就不能使用 v 了
return lim
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
// 结果
/*
27 >= 20
9 20
*/
用牛顿法实现开方函数
在这个例子中,牛顿法是通过选择一个初始点 z 然后重复这一过程求 Sqrt(x)
的近似值:
为了做到这个,只需要重复计算 10 次,并且观察不同的值(1,2,3,……)是如何逐步逼近结果的。
func sqrt(x float64) float64 {
z := 1.0
for v := 0; v < 10; v++{
z = z - (z * z - x)/(2 * z)
fmt.Println(z)
}
return z
}
func main() {
fmt.Println(sqrt(4))
fmt.Println(math.Sqrt(4))
}
// 结果
/*
2.5
2.05
2.000609756097561
2.0000000929222947
2.000000000000002
2
2
2
2
2
2
go math结果:2
*/
switch
一个结构体(struct
)就是一个字段的集合。
除非以 fallthrough 语句结束,否则分支会自动终止。
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.", os)
}
}
// 结果:Go runs on OS X.
// 注:当前实验机器为Macbook
switch 的执行顺序
switch 的条件从上到下的执行,当匹配成功的时候停止。
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.")
}
}
// 结果:
// When's Saturday?
// Too far away.
// 注:当前实验时间周二
没有条件的 switch
没有条件的 switch 同 switch true
一样。
这一构造使得可以用更清晰的形式来编写长的 if-then-else 链。
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.")
}
}
// 结果:Good afternoon.
// 注:当前时间下午一点
defer
defer 语句会延迟函数的执行直到上层函数返回。
延迟调用的参数会立刻生成,但是在上层函数返回前函数都不会被调用
func main() {
defer fmt.Println("world")
fmt.Println("hello")
}
/*
hello
world
*/
defer 栈
延迟的函数调用被压入一个栈中。当函数返回时, 会按照后进先出的顺序调用被延迟的函数调用
func main() {
fmt.Println("counting")
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}
fmt.Println("done")
}
/*
counting
done
9
8
7
6
5
4
3
2
1
0
*/