Go 入门 - 控制流

主要内容来自中文版的官方教程Go语言之旅
目的为总结要点

循环

Go 只有 for循环

for 由三部分组成,用分号间隔开

  • 初始化语句:在第一次迭代之前执行,通常为一句短变量声明(i:=0
  • 条件表达式:在每次迭代之前求值,一旦条件表达式的值是false循环终止
  • 后置语句:在每次迭代结束之后执行

for语言没有小括号,大括号是必须的。

package main

import "fmt"

func main() {
	sum := 0
	for i := 0; i < 10; i++ {
		sum += i
	}
}

需要注意,for语句中声明的变量是局部变量,下面这个例子中省略了后置语句

package main

import "fmt"

func main() {
	var sum int = 1
	for sum := 10; sum < 1000; {
		sum += sum //在这里改变sum并不会影响其他的外层的sum
		fmt.Println(sum)
	}
	fmt.Println(sum)
}
// output 40 80 160 640 1280 1

将所有的分号去掉,可以直接当做while来使用,下面这个例子中省略了初始化语句和后置语句

package main

import "fmt"

func main() {
	sum := 1
	for sum < 1000 {
		sum += sum
		fmt.Println(sum)
	}
	fmt.Println(sum)
}
// output 2 4 8 16 32 64 128 256 512 1024 1024

如果只有for 那么代表无限循环,下面这个例子中省略了所有语句

package main

func main() {
	for {
	}
}

分支

Go也用if来表示分支,表达式无需小括号,必须大括号

func sqrt(x float64) string {
	if x < 0 {
		return sqrt(-x) + "i"
	}
	return fmt.Sprint(math.Sqrt(x))
}

for类似,if在条件表达式之前可以执行一个简单语句,该语句生命的变量作用于仅在if之内

func pow(x, n, lim float64) float64 {
	if v := math.Pow(x, n); v < lim {
		fmt.Println(v)
		return v // 如果v 小于上界,返回v
	} else {
		fmt.Printf("%g >= %g\n", v, lim)
	}
	// 这里开始就不能使用 v 了
	return lim // 否则,返回上界
}

switch

C不同,Go之运行选定的case,不会接着运行之后所有的case,相当于自动提供了break。switch的case语句从上到下顺序求值,知道匹配成功为止

package main

import (
	"fmt"
	"runtime"
)

func main() {
	fmt.Print("Go runs on ")
	switch os := runtime.GOOS; os { // os 的取值不需要为常量,也不需要为整数
	case "darwin":
		fmt.Println("OS X.")
	case "linux":
		fmt.Println("Linux.")
	default:
		// freebsd, openbsd,
		// plan9, windows...
		fmt.Printf("%s.", os)
	}
}

没有条件的switch默认为switch true,比如

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.")
	}
}

defer

defer 是一个关键字,以这个关键字开始的语句会将函数推迟到外层函数返回之后执行。

package main

import "fmt"

func main() {
	defer fmt.Println("world")

	fmt.Println("hello")
}

//output:
//hello
//world

推迟调用的函数其参数会立即求值,但直到外层函数返回前该函数都不会被调用。推迟的函数调用会被压入一个栈中。当外层函数返回时,被推迟的函数会按照后进先出的顺序调用。

package main

import "fmt"

func main() {
	fmt.Println("counting")

	for i := 0; i < 10; i++ {
		defer fmt.Println(i)
	}

	fmt.Println("done")
}
//output
//counting
//done
//9
//8
//7
//6
//5
//4
//3
//2
//1
//0
posted @ 2018-10-14 16:20  JHaoWon  阅读(110)  评论(0编辑  收藏  举报