第七章 接口
< P176 >
在操作interface
时,编译器不会对T
和*T
隐式转换,没有了简便的语法糖,因此T
不拥有*T
的方法;
< P182 >
interface
由两部分组成,type
存储type descriptor
,value
一般存储指针;interface
调用方法是间接调用,先根据type descriptor
找到方法地址,再将value
拷贝作为接收器传入;interface
可以两两比较或与nil
比较;但是如果value
中的类型是不可比较的,会发生panic
;只有type
与type descriptor
都为nil
时,与nil
的比较才为真(受人诟病的坑之一);- 调试时可以用
%T
打印type descriptor
,fmt
通过反射获取;
< P188 >
Sort.Reverse
的实现很巧妙,用结构体reverse
又包装了interface
,reverse
的Less
方法调用匿名内嵌字段interface
的Less
方法,而Reverse
函数又返回满足sort.Interface
的reverse
结构体;
< P191-195 >
http.Handler
是基本的interface
,只要求ServerHTTP
方法,作为ListenAndServe
的第二个参数;- 为了分离逻辑,
net/http
包提供了ServeMux
,将多个http.Handler
集合为一个;在传入方法时用http.HandlerFunc
将方法转为http.Handler
,注意http.HandlerFunc
是一种函数类型,作为ServerHTTP
接收器,满足http.Handler
接口,并在内部调用自己; net/http
提供了默认的ServeMux
,即DefaultServeMux
,在ListenAndServe
第二参数传入nil
即可,用http.HandeFunc
添加路由;- 注意每个请求都会单独创建一个
goroutine
;
< P196 >
errors.New
返回errorString
结构体的指针,所以两个New
出来的error
比较是不相等的;
< P205 >
- 类型断言分两种:
x.(T)
,假如T
是实际类型(concrete type)并且x
为interface
,断言检测通过返回x
的dynamic value
,类型当然是T
,检测失败引发panic
;- 假如
T
是interface
,断言检测会检查x
的dynamic type
是否满足T
,返回结果满足T
,一般结果的方法集更大,失败同样引起panic
;
- 无论
T
是何种类型,对nil
的断言永远失败; - 期望两个返回值的断言检测失败不会
panic
,额外返回值为布尔值表示是否成功,失败时第一个返回值为该类型零值;
< P212 >
在type switch
中,提取值之后的变量类型与当前case
相同,除了多个条件并列时还是interface{}
;(另外企图用%T
打印interface{}
类型的我简直犯傻,本来打印方法的传参就是…interface{}
)