流程控制
- 主要包括以下语句
- for
- if
- else
- switch
- defer
for
- Go 只有一种循环结构—— for 循环。
- 基本的 for 循环包含三个由分号分开的组成部分:
- 初始化语句:在第一次循环执行前被执行
- 循环条件表达式:每轮迭代开始前被求值
- 后置语句:每轮迭代后被执行
例如:
package main
import "fmt"
func main() {
sum := 0
for i := 0;i < 50;i++{
sum += i
}
fmt.Println(sum)
}
- 初始化语句一般是一个短变量声明,这里声明的变量仅在整个 for 循环语句可见。
- 如果条件表达式的值变为 false,那么迭代将终止。 注意:不像 C,Java,或者 Javascript 等其他语言,for 语句的三个组成部分并不需要用括号括起来,但循环体必须用 { } 括起来。
for(续)
- 循环初始化语句和后置语句都是可选的。
package main
import "fmt"
func main() {
sum := 1
for ;sum<1000;{
sum += sum
}
fmt.Println(sum)
}
for 是 Go 的 “while”
- 基于此可以省略分号:C 的 while 在 Go 中叫做 for 。
package main
import "fmt"
func main() {
sum := 3
for sum < 1000{
sum += sum
}
fmt.Println(sum)
}
死循环
- 如果省略了循环条件,循环就不会结束,因此可以用更简洁地形式表达死循环。
package main
func main() {
for{
}
}
if
- 就像 for 循环一样,Go 的 if 语句也不要求用 ( ) 将条件括起来,同时, { } 还是必须有的。
package main
import (
"fmt"
"math"
)
func sqrt(x float64) string{
if x < 0 {
return sqrt(-x) + "i"
}
return fmt.Sprint(math.Sqrt(x))
}
func main(){
fmt.Println(sqrt(2),sqrt(-4))
}
if 的便捷语句
- 跟 for 一样, if 语句可以在条件之前执行一个简单语句。
- 由这个语句定义的变量的作用域仅在 if 范围之内。
package main
import (
"fmt"
"math"
)
func pow(x,n,limit float64) float64{
if v := math.Pow(x,n); v < limit{
return v
}
return limit
}
func main() {
fmt.Println(
pow(3,2,10),
pow(3,4,10),
)
}
注意:这里的v作用范围只在if
范围之内
if 和 else
- 在
if
的便捷语句定义的变量同样可以在任何对应的else
块中使用。
package main
import (
"fmt"
"math"
)
func pow(x, n, limit float64)float64 {
if v := math.Pow(x,n); v < limit{
return v
} else{
fmt.Printf("%g >= %g\n",v,limit)
}
return limit
}
func main() {
fmt.Println(
pow(3, 2, 10),
pow(3, 3, 20),
)
}
执行结果:
27 >= 20
9 20
注意:(提示:两个 pow 调用都在 main 调用 fmt.Println 前执行完毕了。)
练习:循环和函数
- 牛顿法是通过选择一个初始点 z 然后重复这一过程求 Sqrt(x) 的近似值:
package main
import "fmt"
func Sqrt(x float64)float64{
z := float64(1)
for i := 0; i < 10;i++{
z = z - (z*z-x)/2*z
}
return z
}
func main() {
fmt.Println(
Sqrt(2),
)
}
switch
- 除非以 fallthrough 语句结束,否则分支会自动终止。
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Println("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)
}
}
switch 的执行顺序
- switch 的条件从上到下的执行,当匹配成功的时候停止。 例如
switch i {
case 0:
case f():
}
当 i==0
时不会调用 f
。
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Println("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 playground 中的时间总是从 2009-11-10 23:00:00 UTC 开始, 如何校验这个值作为一个练习留给读者完成。
没有条件的 switch
- 没有条件的
switch
同switch true
一样。 - 这一构造使得可以用更清晰的形式来编写长的 if-then-else 链。
package main
import (
"fmt"
"time"
)
func main() {
today := time.Now()
switch {
case today.Hour() < 12:
fmt.Println("Good morning.")
case today.Hour() < 17:
fmt.Println("Good aftertoon.")
default:
fmt.Println("Good evening.")
}
}
defer
- defer 语句会延迟函数的执行直到上层函数返回。
- 延迟调用的参数会立刻生成,但是在上层函数返回前函数都不会被调用。
package main
import "fmt"
func main() {
defer fmt.Println("world")
fmt.Println("Hello")
}
__注意:简单的理解第二点,就上面的例子,也就是知道main()
返回前都不会调用defer fmt.Println("world")
defer 栈
- 延迟的函数调用被压入一个栈中。当函数返回时, 会按照后进先出的顺序调用被延迟的函数调用。
package main
import "fmt"
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
本文由 zealzhangz 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为:
2018/02/05 23:37