interface接口和defer场景分析
接口
接口这里主要两点:
- 设计业务结构时采用依赖倒转:业务层向下依赖抽象层,实现层向上依赖抽象层。
相比于之前:
之后:
-
注意struct中嵌套interface和不嵌套interface的区别:
type Myinterface interface{func Do() }// 未嵌套interface type Struct1 struct{ }func (*Struct1) Do(){...}// 嵌套interface type Struct2 struct{Myinterface }struct1 := &Struct1{} struct2 := &Struct2{Myinterface : struct1 }// 当然,mystruct2在Interface被赋值的前提下,也可以重写部分Myinterface的方法 func (*Struct2) Do(){...2}// 结果相同,mystruct2直接复用mystruct1的Do方法 struct1.Do() struct2.Do()// 结果改变 struct2.Do()
注意本质:
任何实现接口的方式都要全部实现接口的方法,可以组合方法。
defer场景分析
场景:
-
执行顺序:栈(先进后出).
-
defer 和 return 的执行顺序:return 表达式先执行;defer 后执行.
-
函数返回值在栈上:①有名 ②作用于整个函数域.
-
基于 3,函数遇到 defer 时,defer 会修改基于 return 的值.
-
defer + panic(不捕获,异常传递,程序异常终止,调用栈正常)
-
defer + panic(捕获,异常传递中断,原函数继续执行,调用栈恢复)
总之:panic 后语句不执行. -
defer 中有 panic:recover 只捕获一个 panic(最后一个 panic )
panic 覆盖(后覆盖前). -
defer + 子函数:defer function (1, function [2,0]);先执行参数表达式;再执行函数.
-
defer 压栈时的参数已经确定(形参不变,实参可变).
eg: {...defer func (i int){fmt.Println(i) -> i=0fmt.Println(t) -> t=2}(t)t=2 -> t=2return } defer 压栈时参数已经确定赋值给 i,i为0,然后被修改为2,则t=2