package main
import "fmt"
// 核心规则4
// return 语句不是原子操作,它分为两步:
//第一步:将返回值(若有命名返回值则直接赋值,若无则创建临时变量)赋值为 return 后面的表达式。
//第二步:执行所有已注册的 defer 函数(后注册先执行)。
//第三步:函数真正返回。
//命名返回值(如 (r int))在函数开始时就已声明并初始化为零值,return 语句会先给这个变量赋值。
// defer 函数的参数在 defer 语句被执行到时就已经求值(值拷贝),而 defer 函数体内部对变量的修改是否影响外部,取决于它捕获的是变量本身(闭包)还是副本(参数)。
func f1() (r int) {
defer func() {
r++
}()
return 0 //r=0 再执行 defer r=1
}
func f2() (r int) {
t := 5
defer func() {
t = t + 5
}()
return t // 创建临时变量=5 t+5无效
}
func f3() (r int) {
defer func(r int) {
r = r + 5
}(r)
return 1 // r=1 defer 使用拷贝了一份,使用内部变量
}
func f4() (r int) {
defer func() {
r = r + 5
}()
return 1 // r=1 defer后=6
}
func main() {
fmt.Println(f1()) //1
fmt.Println(f2()) //5
fmt.Println(f3()) //1
fmt.Println(f4()) //6
}
go 的defer 执行顺序
GO多态
1.多态是什么
通俗讲就是 “一个接口,多种形态”。它指的是:同一个行为(方法名),作用于不同的对象时,会产生不同的执行结果。
2.举例子
// 定义一个函数,它接受 A 接口类型
func Process(a A) {
// 这里不管传入的是谁,直接调用 ShowA
fmt.Println(a.ShowA())
}
func main() {
w1 := Work{3} // ShowA 返回 i+10
w2 := OtherWork{5} // 假设另一个结构体,ShowA 返回 i*2
Process(w1) // 输出 13
Process(w2) // 输出 10(假设 OtherWork 的 ShowA 是乘以2)
}
在这个例子里:
Process 函数只关心参数是 A 类型,它根本不知道传入的是 Work 还是 OtherWork。
但运行时,w1 和 w2 各自执行了自己独有的 ShowA 逻辑。