Browse Source

恐慌、恢复

fengchun_yuan 2 years ago
parent
commit
580aea5ffc
2 changed files with 78 additions and 1 deletions
  1. 55 1
      Go语言101/sync/main.go
  2. 23 0
      Go语言101/入门.md

+ 55 - 1
Go语言101/sync/main.go

@@ -69,7 +69,61 @@ func main() {
 	// 	defer fmt.Println("not reachable")
 	// }
 	{
-		fmt.Println(Triple(5))
+		// 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("恐慌")
+
 	}
 }
 

+ 23 - 0
Go语言101/入门.md

@@ -806,3 +806,26 @@ func Triple(n int) (r int) {
 ```
 
 ## 协程和延迟调用的实参的估值时刻
+
+延迟调用的实参,是在此延迟调用被推入延迟调用队列是被估值(确定的)。
+
+匿名函数体内表达式是在此函数被执行时候才被估值的。
+
+```go
+12| func(a, b int) {
+13| println("a*a + b*b =", a*a + b*b) // a*a + b*b = 25
+14| }(x, y) // 立即调用并传递两个实参。 把x,y传递给a,b
+```
+
+## 恐慌panic和恢复recover
+
+Go不支持异常抛出和捕获,而是推荐使用返回值显式返回错误。 不过,Go支持一套 和异常抛出/捕获类似的机制。此机制称为恐慌/恢复(panic/recover)机制。
+
+可用调用内置函数panic来产生一个恐慌以使当前协程进入恐慌状态。
+进入恐慌状况是另一种使当前函数调用开始返回的途径。 一旦一个函数调用产生一 个恐慌,此函数调用将立即进入它的退出阶段。
+如果一个协程在恐慌状态下退出,整个程序会崩溃。
+通过在一个**延迟函数调用之中调用内置函数recover**,当前协程中的一个恐慌可以被消除,从而使当前协程进入正常状况。
+
+**恐慌后,当前函数进入退出状态,只会执行defer队列中的代码**
+
+#