我正在读this slideshow,上面写着:
var hits struct {
sync.Mutex
n int
}
hits.Lock()
hits.n++
hits.Unlock()
那是如何工作的?似乎hits
不是由组成互斥锁和整数,但是 是互斥锁和整数?
答案 0 :(得分:3)
是构图。使用匿名字段(嵌入式字段),包含的结构将具有嵌入式类型的值,您可以引用它:不合格的类型名称充当字段名称。
所以您可以轻松地编写:
hits.Mutex.Lock()
hits.n++
hits.Mutex.Unlock()
嵌入类型时,嵌入类型的字段和方法会被提升为提升,因此无需指定字段名称(即嵌入类型名称)就可以引用它们。语法糖。引用自Spec: Selectors:
选择器
f
可以表示类型为f
的字段或方法T
,或者可以引用嵌套{{3 }},共f
。
除字段/方法提升之外,嵌入类型的embedded field也将包含嵌入类型的方法集。引用自method set
鉴于结构类型为
T
和Spec: Struct types:S
,在该方法的方法集中包含了改进的方法,如下所示:
如果
T
包含嵌入字段S
,则T
的{{3}}和S
都包括接收者{{1} }。*S
的方法集还包括使用接收者T
的提升方法。如果S包含一个嵌入字段* T,则S和* S的方法集都包括带有接收者T或* T的提升方法。
这不是面向对象的继承,而是类似的东西。当您要实现接口时,这很方便:如果您嵌入了已经实现该接口的类型,那么您的struct类型也将嵌入。您还可以提供一些方法的自己的实现,这给人一种方法被覆盖的感觉,但是请不要忘记,表示嵌入类型的方法的选择器将获得嵌入值作为接收者(而不是嵌入器值),并且表示您在struct类型上定义的方法的选择器(可能会“隐藏”嵌入式类型的方法,也可能不会)将嵌入程序的struct值作为接收器。
答案 1 :(得分:0)
这称为嵌入,hits
由sync.Mutex
和int
组成。这应该是正确的,因为Go中确实没有继承。成员与结构之间的关系更多是“具有”关系,而不是“是”关系。
Read here for a more complete explanation
从链接引用
嵌入类型的方法是免费提供的
这意味着您可以像hits.Lock()
那样访问它们,而不必使用较长的形式hits.Mutex.Lock()
,因为函数Lock()
并不明确。
答案 2 :(得分:0)
请参见fmt.Printf("%#v\n", &hits)
// &struct { sync.Mutex; n int }{Mutex:sync.Mutex{state:0, sema:0x0}, n:1}
变量的Go语法表示形式:
hits.Mutex.Lock()
hits.Mutex.Unlock()
声明变量时,它只是使用默认值初始化struct中的字段。
此外,编译器会自动将嵌入式结构的名称设置为字段。因此,您也可以像这样访问:
sync.Mutex
您可以访问{{1}}的所有方法和导出字段(如果有)。