接口
接口这里主要两点:
- 设计业务结构时采用依赖倒转:业务层向下依赖抽象层,实现层向上依赖抽象层。
相比于之前:
之后:
-
注意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=0 fmt.Println(t) -> t=2 }(t) t=2 -> t=2 return } defer 压栈时参数已经确定赋值给 i,i为0,然后被修改为2,则t=2