package main import ( "fmt" "log" "math/rand" "sync" "time" ) var wg sync.WaitGroup func SayGreetings(greeting string, times int) { for i := 0; i < times; i++ { log.Println(greeting) d := time.Second * time.Duration(rand.Intn(5)) / 2 time.Sleep(d) } wg.Done() // 通知当前任务已经完成。 } func main() { // { // //waitgroup 样例 // rand.Seed(time.Now().UnixNano()) // log.SetFlags(0) // wg.Add(2) // 注册两个新任务。 // go SayGreetings("hi!", 10) // go SayGreetings("hello!", 10) // wg.Wait() // 阻塞在这里,直到所有任务都已完成。 // } // { // wg.Add(1) // go func() { // time.Sleep(time.Second * 2) // wg.Done() // wg.Wait() // 阻塞在此 // }() // wg.Wait() // 阻塞在此 // } // { // fmt.Println(runtime.NumCPU()) //最多并行执行的协程数量 // } // { // defer fmt.Println("The third line.") // defer fmt.Println("The second line.") // fmt.Println("The first line.") // // first second third // } // { // defer fmt.Println("9") // fmt.Println("0") // defer fmt.Println("8") // fmt.Println("1") // if false { // defer fmt.Println("not reachable") // } // defer func() { // defer fmt.Println("7") // fmt.Println("3") // defer func() { // fmt.Println("5") // fmt.Println("6") // }() // fmt.Println("4") // }() // fmt.Println("2") // return // defer fmt.Println("not reachable") // } { // fmt.Println(Triple(5)) } { //协程和延迟调用的实参的估值时刻 //延迟调用的实参,是在此延迟调用被推入延迟调用队列时被估值的。 //匿名函数体内的表达式是在此函数被执行的时候才被逐渐估值的,不管是普通调用还是延迟、协程调用 // { // //defer // func() { // for i := 0; i < 3; i++ { // defer fmt.Println("a:", i) // } // }() // fmt.Println() // func() { // for i := 0; i < 3; i++ { // defer func() { // fmt.Println("b:", i) // }() // } // }() // //a:2 1 0 // //b:3 3 3 // } // { // //同样的估值时刻规则也适用于协程调用 // var a = 123 // go func(x int) { // // 形参x遮挡了外层声明的变量x // fmt.Println(x) // time.Sleep(time.Second) // fmt.Println(x, a) // 123 789 // fmt.Println(x, x) // 123 123 拷贝 // }(a) // 将实参a传递给形参x // a = 789 // time.Sleep(2 * time.Second) // } } // { // x, y := 3, 4 // z := func(a, b int) (c int) { // println("a*a + b*b =", a*a+b*b) // a*a + b*b = 25 // return a*a + b*b // }(x, y) // 立即调用并传递两个实参。 把x,y传递给a,b // fmt.Println(z) // } { //恐慌、恢复 fmt.Println("hi") defer func() { v := recover() fmt.Println("恐慌被恢复了", v) }() panic("恐慌") } } func Triple(n int) (r int) { defer func() { fmt.Println(r) r += n // 修改返回值 fmt.Println(r) }() return n + n // <=> r = n + n; return // return 10 ——> r=10 ——> 进入defer r=15 ——> return 15 //这个函数先执行完return 再执行defer内部,很神奇。 }