在 Go 中调用 C 代码:
/*
int sum(int a, int b) {
return a+b;
}
*/
import "C"
func main() {
println(C.sum(1, 1))
}
defer:函数退出前一定会执行 defer 后的语句。
思路:
1.1 堆上分配
sched.deferpool
deferpool
deferpool
取出执行deferpool
记录在线程结构体 p
上:
type p struct {
// ...
deferpool []*_defer // pool of available defer structs (see panic.go)
deferpoolbuf [32]*_defer
// ...
}
1.2 栈上分配
2.1 开放编码
func main() {
defer fmt.Println("defer1")
defer fmt.Println("defer2")
fmt.Println("main")
}
panic
func main() {
go func() {
panic("panic")
fmt.Println("do")
}()
fmt.Println("main")
time.Sleep(1 * time.Second)
/*
main
panic: panic
*/
}
panic + defer
func main() {
defer fmt.Println("defer1")
go func() {
defer fmt.Println("defer2")
panic("panic1")
fmt.Println("do")
}()
fmt.Println("main")
time.Sleep(1 * time.Second)
/**
main
defer2
panic: panic1
*/
}
panic + defer + recover
在 defer 中执行 recover 可以拯救协程
func main() {
defer fmt.Println("defer1")
go func(){
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered. Error: ", r)
}
}()
panic("panic1")
fmt.Println("do")
}()
fmt.Println("main")
time.Sleep(1 * time.Second)
/**
main
Recovered. Error: panic1
defer1
*/
}
func main() {
s := "moody"
stype := reflect.TypeOf(s)
fmt.Println("TypeOf s:", stype)
svalue := reflect.ValueOf(s)
fmt.Println("ValueOf s:", svalue)
}
元数据
func main() {
s := "go"
// 对象的类型
// 把对象的类型表示成一个接口
stype := reflect.TypeOf(s)
fmt.Println("TypeOf s:", stype) // TypeOf s: string
// 对象的值
// 把对象的值表示成一个接口
svalue := reflect.ValueOf(s)
fmt.Println("ValueOf s:", svalue) // ValueOf s: go
s2 := svalue.Interface().(string)
//
fmt.Println("s2:", s2) // s2: go
}
反射调用方法
通过反射调用方法,实现用户方法和框架解耦
func MyAdd(a, b int) int { return a + b }
func CallAdd(f func(a int, b int) int) {
v := reflect.ValueOf(f)
if v.Kind() != reflect.Func {
return
}
argv := make([]reflect.Value, 2)
argv[0] = reflect.ValueOf(1)
argv[1] = reflect.ValueOf(1)
result := v.Call(argv)
fmt.Println(result[0].Int())
}
func main() {
CallAdd(MyAdd)
}