上卷 程序设计
中卷 标准库
- 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
下卷 运行时
源码剖析
附录
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
5.5.1 匿名
所谓匿名字段(anonymous field),是指没有名字,仅有类型的字段。也被称作嵌入字段、嵌入类型。
- 隐式以类型名为字段名。
- 嵌入类型与其指针类型隐式字段名相同。
- 像直属字段那样直接访问嵌入类型成员。
type Attr struct { perm int } type File struct { Attr // Attr: Attr name string } func main() { f := File { name: "test.dat", // 必须显式名称初始化。 // perm: 0644, // ~~~~ unknown field 'perm' in struct literal of type File Attr: Attr{ perm: 0644, }, } // 像直属字段访问嵌入字段。 fmt.Printf("%s, %o\n", f.name, f.perm) }
嵌入其他包里的类型,隐式字段名字不含包名。
type data struct { os.File // File: os.File } func main() { d := data{ File: os.File{}, } fmt.Printf("%#v\n", d) }
除 接口指针 和 多级指针 以外的任何 命名类型 都可作为匿名字段。
type data struct { *int // int: *int(星号不是名字组成部分) // int // ~~~ int redeclared fmt.Stringer // *fmt.Stringer // ~~~~ embedded field type cannot be a pointer to an interface } func main() { _ = data{ int: nil, Stringer: nil, } }
重名
直属字段与嵌入类型成员存在重名问题。
编译器优先选择直属命名字段,或按嵌入层次逐级查找匿名类型成员。
如匿名类型成员被外层同名遮蔽,那么必须用显式字段名。
type File struct { name []byte } type Data struct { File name string // 和 File.name 重名。 } func main() { d := Data{ name: "data", File: File{ []byte("file") }, } d.name = "data2" // 优先选择直属命名字段。 d.File.name = []byte("file2") // 显式字段名。 fmt.Println(d.name, d.File.name) }
如多个相同层次的匿名类型成员重名,就只能用显式字段名,因为编译器无法确定目标。
type File struct { name string } type Log struct { name string } type Data struct { File Log } func main() { d := Data{} // d.name = "name" // ~~~~~~ ambiguous selector d.name d.File.name = "file" d.Log.name = "log" }
Go 并非传统意义上的 OOP 语言(封装、继承和多态),仅实现了最小机制。
匿名嵌入是 组合 (composition),而非 继承 (inheritance)。
结构虽然承载了 class 功能,但无法 多态 (polymorphisn),只能以方法集配合接口实现。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论