上卷 程序设计
中卷 标准库
- bufio 1.18
- bytes 1.18
- io 1.18
- container 1.18
- encoding 1.18
- crypto 1.18
- hash 1.18
- index 1.18
- sort 1.18
- context 1.18
- database 1.18
- connection
- query
- queryrow
- exec
- prepare
- transaction
- scan & null
- context
- tcp
- udp
- http
- server
- handler
- client
- h2、tls
- url
- rpc
- exec
- signal
- embed 1.18
- plugin 1.18
- reflect 1.18
- runtime 1.18
- KeepAlived
- ReadMemStats
- SetFinalizer
- Stack
- sync 1.18
- atomic
- mutex
- rwmutex
- waitgroup
- cond
- once
- map
- pool
- copycheck
- nocopy
- unsafe 1.18
- fmt 1.18
- log 1.18
- math 1.18
- time 1.18
- timer
下卷 运行时
源码剖析
附录
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
6.1 匿名嵌入
像访问匿名类型成员那样调用其方法,由编译器负责查找。
type data struct { sync.Mutex buf [1024]byte } func main() { d := data{} d.Lock() // sync.(*Mutex).Lock() defer d.Unlock() }
同名遮蔽。利用这种特性,实现类似覆盖(override)操作。
和匿名字段访问类似,按最小深度优先原则。
如两个同名方法深度相同,那么编译器无法作出选择(ambiguous selector),需显式指定。
type E struct{} type T struct { E } func (E) toString() string { return "E" } func (t T) toString() string { return "T." + t.E.toString() } // ---------------------------------- func main() { var t T println(t.toString()) // T.E println(t.E.toString()) // E }
同名,但签名不同的方法。
type E struct{} type T struct { E } func (E) toString() string { return "E" } func (T) toString(s string) string { return "T: " + s } // ------------------------------------------ func main() { var t T // println(t.toString()) // ~~~~~~~~ not enough arguments in call to t.toString // have () // want (string) // 选择深度最小的方法。 println(t.toString("abc")) // T: abc // 明确目标。 println(t.E.toString()) // E }
匿名类型的方法只能访问自己的字段,对外层一无所知。
package main type E struct { x int } type T struct { x string E } func (e *E) do() { e.x = 100 println(e.x) } func (t *T) do() { t.x = "abc" println(t.x) } // ------------------------------------------ func main() { var t T t.do() // abc t.E.do() // 100 } /* 可以看出 t.E.do 的 receiver 仅限于自己那段内存。 即便把 E 作第一字断,各自方法内的寻址偏移也指向自己的内存区域。 $ go build -gcflags "-l" $ go tool objdump -S -s "main\.main" ./test func main() { var t T t: T 0x455314 MOVQ $0x0, 0x8(SP) 0x8 +---------+ 0x45531d MOVUPS X15, 0x10(SP) | T.x.ptr | 0x10 +---------+ t.do() // abc | T.x.len | 0x455323 LEAQ 0x8(SP), AX 0x18 +---------+ 0x455328 CALL main.(*T).do(SB) | T.E.x | +---------+ t.E.do() // 100 0x45532d LEAQ 0x18(SP), AX 0x455332 CALL main.(*E).do(SB) } */
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论