-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
Description
-
for
没有
(), 始终需要{}for i := 0; i < 10; i++ { sum += i }只天中间项,这样就相当于
whilefor sum < 1000 { sum += sum }中间项都不填就是死循环了
for { } -
if
没有
(), 始终需要{}if x < 0 { return sqrt(-x) + "i" }可以在
if后声明变量,变量的作用域为整个if语句if v := math.Pow(x, n); v < lim { return v } else { fmt.Printf("%g >= %g\n", v, lim) } -
Switch
可以在
Switch后声明变量,变量的作用域为整个Switch语句
每个case语句默认会加上break;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.") } }没有变量会默认为
true,相当于if-elsefunc 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是Go语言提供钩子。该钩子在当前函数执行完毕后(包括通过return正常结束或者panic导致的异常结束)执行defer语句通常用于一些成对操作的场景:打开连接/关闭连接;加锁/释放锁;打开文件/关闭文件等执行过程
- 每次defer语句执行的时候,会把函数"压栈",函数参数会被拷贝下来
- 当外层函数(非代码块,如一个for循环)退出时,defer函数按照定义的逆序执行
- 如果defer执行的函数为nil, 那么会在最终调用函数的产生panic
一切从go函数返回值可以被命名说起
如下,
split的返回值被命名为x和yfunc split(sum int) (x, y int) { x = sum * 4 / 9 y = sum - x return }简单
hello world函数func helloWorld() { return "Hello world" }可被理解成
func helloWorld(rval string) { rval = "Hello world" return }defer关键字在编译过后就相当于在
return关键字前执行defer_funcrval = xxx defer_func return演示
函数压栈操作
func main() { for i := 0; i < 5; i++ { defer fmt.Println(i) } }$ go run main.go 4 3 2 1 0int类型为值拷贝,所以返回值为5
func f() int { i := 5 defer func() { i++ }() return i }func f() (rval int) { i := 5 rval = i func() { i++ }() return }返回变量为
result,result在defer被修改。所以返回值为1func f1() (result int) { defer func() { result++ }() return 0 }func f1() (result int) { result = 0 func() { result++ }() return }int类型为值拷贝,所以返回值为5func f2() (r int) { t := 5 defer func() { t = t + 5 }() return t }func f2() (r int) { t := 5 r = t func() { t = t + 5 }() return }函数的值都会被拷贝,不影响原来的参数。返回值为1
func f3() (r int) { defer func(r int) { r = r + 5 }(r) return 1 }func f3() (r int) { r = 1 func(r int) { r = r + 5 }(r) return } -
panic和recover。可以简化错误处理
panic会先处理完当前goroutine已经defer挂上去的任务,执行完毕后再退出整个程序可以通过
recover在当前goroutine捕捉panic,recover只在defer的函数中有效package main import "fmt" func main() { f() fmt.Println("Returned normally from f.") } func f() { defer func() { if r := recover(); r != nil { fmt.Println("Recovered in f", r) } }() fmt.Println("Calling g.") g(0) fmt.Println("Returned normally from g.") } func g(i int) { if i > 3 { fmt.Println("Panicking!") panic(fmt.Sprintf("%v", i)) } defer fmt.Println("Defer in g", i) fmt.Println("Printing in g", i) g(i + 1) }