Golang初学:struct 的 嵌入式字段(an embedded field)
go version go1.22.1 windows/amd64
Windows 11 + amd64
x86_64 x86_64 GNU/Linux
---
序章
在 测试 标准库 sort 包的 Example (SortWrapper) 时,遇到了看不懂的代码,查询 Specification 才知,这叫做 an embedded field(嵌入式字段)。
关键词:
#嵌入式字段 #方法提升(升级)
标准库 sort:ben发布于博客园
The Go Programming Language Specification 之 Struct types
https://golang.google.cn/ref/spec#Struct_types
看不懂的代码
type Organ struct {
Name string
Weight Grams
}
type Organs []*Organ
func (s Organs) Len() int { return len(s) }
func (s Organs) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
// ByName implements sort.Interface by providing Less and using the Len and
// Swap methods of the embedded Organs value.
type ByName struct{ Organs }
这里的 类型 Organs 是一个 指针切片,而 ByName 是一个新类型,可是,这个 struct 里面 直接就用了 Organs,字段名呢?
而且注释说,type ByName 直接就拥有 type Organ 的 Len、Swap 函数。
在 Example 完整代码 中 type ByName 还实现了 Less 函数,就这样,ByName 完全实现了 sort.Interface 接口的 3个函数。
Specification 之 Struct types 解读
原文:ben发布于博客园
Struct types Field names may be specified explicitly (IdentifierList) or implicitly (EmbeddedField). Within a struct, non-blank field names must be unique. |
explicitly adv. 明白地,明确地,明显地 implicitly adv. 含蓄地; 暗示地; 无疑问地; 无保留地 |
定义:
关于 an embedded field
A field declared with a type but no explicit field name is called an embedded field. An embedded field must be specified as a type name T or as a pointer to a non-interface type name *T, and T itself may not be a pointer type. The unqualified type name acts as the field name. |
没有名称,就是 嵌入式字段。 可以是 类型名,也可以是 非接口类型名的指针。 T自身不能是指针。 |
关于方法提升 promoted methods
A field or method f of an embedded field in a struct x is called promoted if x.f is a legal selector that denotes that field or method f. |
嵌入式字段的 字段和方法 f 可以被 结构体 x 直接使用 x.f。 前提是,x.f 是 合法的 selector。ben发布于博客园 |
这里提升的不只是 方法,还有 字段。ben发布于博客园
TODO a legal selector:
https://golang.google.cn/ref/spec#Selectors
promoted methods 详情:ben发布于博客园
Given a struct type S and a named type T, promoted methods are included in the method set of the struct as follows: 1)If S contains an embedded field T, the method sets of S and *S both include promoted methods with receiver T. The method set of *S also includes promoted methods with receiver *T. 2)If S contains an embedded field *T, the method sets of S and *S both include promoted methods with receiver T or *T. |
1) 用类型名 T 父类型 S 和 *S 拥有 类型 T 的所有方法,但是,*S 还拥有 接收者为 *T 的方法——而 S 没有(和 2 的区别)。 2) 用类型名指针 *T 父类型 S 和 *S 拥有 类型 T 和 *T 的所有方法。 |
自测代码
// 在 标准库 sort 的示例基础上更新
// 新增,多嵌入式字段
type ByName2 struct {
Organs
string
float64
}
type ByName3 struct {
// 加了 os,ByName3 没有 Len、Swap 两个函数了,非嵌入式
os Organs
}
// 嵌入式字段 出现位置测试
type ByName4 struct {
s1 string
i1 int
Organs
}
func test() {
fmt.Println("ByName2:")
//too few values in struct literal of type ByName2
// bn2 := ByName2{s} // no
bn2 := ByName2{s, "str", 1.1} // ok
fmt.Println(bn2)
fmt.Println(bn2.float64, bn2.string, bn2.Organs, bn2.Len())
fmt.Println("ByName3:")
bn3 := ByName3{s}
fmt.Println(bn3)
fmt.Println(bn3.os, bn3.os.Len())
fmt.Println("ByName4:")
bn4 := ByName4{"", 12, s}
fmt.Println(bn4)
fmt.Println(bn4.Len())
}
注,以上仅测试了 嵌入式字段 的部分内容,大家可以根据前文的解读设计测试代码。
END.
如有错漏,还请不吝指正🀄
本文链接:
https://www.cnblogs.com/luo630/p/18204949
ben发布于博客园
参考资料
1、
ben发布于博客园
ben发布于博客园