package main // o O func f1() { defer println("f1-start") f2() defer println("f1-end") } func f2() { defer println("f2-start") f3() defer println("f2-end") } func f3() { defer println("f3-start") //panic(0) defer println("f3-end") } func main() { f1() }
f3-end
f3-start
f2-end
f2-start
f1-end
f1-start
package main // o O func f1() { defer println("f1-start") f2() defer println("f1-end") } func f2() { defer println("f2-start") f3() defer println("f2-end") } func f3() { defer println("f3-start") panic(0) defer println("f3-end") } func main() { f1() }
defer 执行原理
The Evaluation Moment of Deferred Function Values
The called function (value) in a deferred function call is evaluated when the call is pushed into the deferred call stack of the current goroutine. For example, the following program will print
false
.
package main
import "fmt"
func main() {
var f = func () {
fmt.Println(false)
}
defer f()
f = func () {
fmt.Println(true)
}
}
GOROOT=C:Go #gosetup GOPATH=D:myGOPATH #gosetup C:Goingo.exe build -o D:mytmpOLDc\___go_build_run_go.exe D:/myGPrject/lChan/run.go #gosetup D:mytmpOLDc\___go_build_run_go.exe #gosetup f3-start f2-start f1-start panic: 0 goroutine 1 [running]: main.f3() D:/myGPrject/lChan/run.go:16 +0x71 main.f2() D:/myGPrject/lChan/run.go:11 +0x5e main.f1() D:/myGPrject/lChan/run.go:6 +0x5e main.main() D:/myGPrject/lChan/run.go:21 +0x27 Process finished with exit code 2
package main // o O func main() { var m map[string]int m["a"] = 1 if v := m["b"]; v != nil { println(v) } }
# command-line-arguments
lMap
un.go:8:20: cannot convert nil to type int
package main // o O func main() { var m map[string]int m["a"] = 1 //if v := m["b"]; v != nil { // println(v) //} }
panic: assignment to entry in nil map
goroutine 1 [running]:
main.main()
D:/myGPrject/lMap/run.go:7 +0x52
package main // o O func main() { m := make(map[string]int) m["a"] = 1 println(m["a"]) println(m["b"]) // 键不存在,返回零值 int 的零值是0 n := make(map[string]string) n["a"] = "stra" println(n["a"]) println(n["b"]) // string 的零值是空 }
package main // o O func main() { m := make(map[string]int) m["a"] = 1 if v := m["b"]; v != 0 { println(v) } }
package main // o O const N = 3 func main() { m := make(map[int]*int) for i := 0; i < N; i++ { m[i] = &i } for _, v := range m { print(*v) } }
// Unmarshal parses the JSON-encoded data and stores the result
// in the value pointed to by v. If v is nil or not a pointer,
// Unmarshal returns an InvalidUnmarshalError.
json 编码解码
package main import ( "encoding/json" "fmt" ) // o O type Result struct { status int } func main() { data := []byte(`{"status":200}`) result := Result{} if err := json.Unmarshal(data, result); err != nil { fmt.Println("error", err) return } fmt.Println("result=%+v", result) }
error json: Unmarshal(non-pointer main.Result)
借助map
package main import ( "encoding/json" "fmt" ) // o O func main() { data := []byte(`{"status":200}`) result := make(map[string]int) if err := json.Unmarshal(data, &result); err != nil { fmt.Println("error", err) return } fmt.Printf("result=%d", result["status"]) }
https://go101.org/article/defer-more.html
More about Deferred Function Calls
package main import "fmt" func main() { var f = func () { fmt.Println(false) } defer f() f = func () { fmt.Println(true) } }
package main type T int func (t T) M(n int) T { print(n) return t } func main() { var t T // "t.M(1)" is the receiver argument of the method // call ".M(2)", so it is evaluated before the // ".M(2)" call is pushed into deferred call stack. defer t.M(1).M(2) t.M(3).M(4) }
package main import "fmt" func main() { defer func() { fmt.Println(recover()) }() defer panic(3) defer panic(2) defer panic(1) panic(0) }