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发布于博客园

https://pkg.go.dev/sort

 

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
A struct is a sequence of named elements, called fields, each of which has a name and a type.

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发布于博客园

 

posted @ 2024-05-21 21:21  快乐的欧阳天美1114  阅读(58)  评论(0编辑  收藏  举报