嵌入式结构 [英] Embedded struct
问题描述
是否可以在不使用嵌入式结构的情况下继承类型的方法?
Is it possible to inherit methods of a type without using embedded structs?
第一段代码是将Property
结构嵌入到Node
中的工作代码,我可以调用node.GetString
,这是Properties
上的一种方法.我不喜欢这样的事情是当我初始化Node
时,我具有(?)来初始化其中的Properties
结构.有没有解决的办法?
The first snippet of code is working code that embeds the Property
struct in Node
and I'm able to call node.GetString
that's a method on Properties
. The thing I don't like about this is when I initialize Node
I have(?) to initialize the Properties
struct within it. Is there a way around this?
package main
import "fmt"
type Properties map[string]interface{}
func (p Properties) GetString(key string) string {
return p[key].(string)
}
type Nodes map[string]*Node
type Node struct {
*Properties
}
func main() {
allNodes := Nodes{"1": &Node{&Properties{"test": "foo"}}} // :'(
singleNode := allNodes["1"]
fmt.Println(singleNode.GetString("test"))
}
最终,我想做类似以下的事情.其中Node
是Properties
类型,并且初始化也不需要初始化Property
结构.以下代码不起作用,但可能清楚我的目标是什么.
Ultimately, I would like to do something like the following. Where Node
is of type Properties
and initializing does not require initializing a Property
struct too. The following code doesn't work but may be clear what my goal is.
package main
import "fmt"
type Properties map[string]interface{}
func (p Properties) GetString(key string) string {
return p[key].(string)
}
type Nodes map[string]*Node
type Node Properties
func main() {
allNodes := Nodes{"1": &Node{"test": "foo"}} // :)
singleNode := allNodes["1"]
fmt.Println(singleNode.GetString("test")) // :D
}
我将添加更多使用Properties
方法的结构,这就是我要问的原因.如果我只有Node
,那么我将只有用于Node
的方法并完成.但是因为我将拥有超过Node
的资源,所以我发现将相同的方法添加到所有嵌入Properties
I'll be adding more structs that will use Properties
's methods which is why I'm asking. If I only had Node
, I would just have methods for Node
and be done. But because I'll have more than Node
I find it kind of redundant to add the same methods to all the structs that embed Properties
对于确切的问题,我想更多了,我想使用Node
中的Properties
方法,而不必初始化Properties
.
I guess more to the exact problem, I want to use Properties
methods from Node
without having to initialize Properties
.
推荐答案
因此,您在这里遇到了Go的特质.嵌入是一个结构中的方法可以被提升"以使其似乎存在于另一个结构中的唯一方法.虽然type Node Properties
应该在Node
上公开Properties
方法,这很直观,但是该语法的作用是使Node
承担Properties
的内存布局,而不是其任何方法.
So you're running into an idiosyncrasy of Go here. Embedding is the only way in which methods of one struct can get "promoted" to appear to exist on another struct. While it feels intuitive that type Node Properties
should expose the Properties
methods on Node
, that effect of that syntax is for Node
to take on the memory layout of Properties
but not any of its methods.
它没有解释为什么做出这种设计选择,但是 Go Spec 位于如果干燥,则最不具体.如果您完全按照原样阅读它,没有任何解释,那么它是非常准确的:
It doesn't explain why this design choice was made but the Go Spec is at least specific if dry. If you read it exactly as it appears, with no interpretation, it is very accurate:
接口类型的方法集是其接口.任何其他类型T的方法集都包含所有已声明的方法 接收器类型为T
The method set of an interface type is its interface. The method set of any other type T consists of all methods declared with receiver type T
GetString
的接收器类型为Properties
而不是Node
,认真地,将规范解释为您是没有想象力的会计师.这么说:
GetString
has a receiver of type Properties
not Node
, seriously, interpret the spec like you're an accountant with no imagination. With that said:
其他规则适用于包含匿名字段的结构,如有关结构类型的部分所述.
Further rules apply to structs containing anonymous fields, as described in the section on struct types.
...
如果x.f是表示该字段或方法f的合法选择器,则结构x中匿名字段的字段或方法f称为提升.
A field or method f of an anonymous field in a struct x is called promoted if x.f is a legal selector that denotes that field or method f.
提升字段的行为类似于结构的普通字段,除了它们 不能用作结构的复合文字中的字段名称.
Promoted fields act like ordinary fields of a struct except that they cannot be used as field names in composite literals of the struct.
给定一个结构类型S和一个名为T的类型,提升的方法是 包含在该结构的方法集中的方法如下:
Given a struct type S and a type named T, promoted methods are included in the method set of the struct as follows:
- 如果S包含匿名字段T,则S和* S的方法集 包括接收方T的提升方法.* S的方法集也 包括带有接收器* T的改进方法.
- 如果S包含匿名 字段* T,S和* S的方法集都包含提升的方法 接收者为T或* T.
- If S contains an anonymous 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.
- If S contains an anonymous field *T, the method sets of S and *S both include promoted methods with receiver T or *T.
关于复合文字的这一行迫使您在创建的每个Node
中声明Properties
.
That line about composite literals is this thing that forces you to declare Properties
inside every Node
you create.
p.s.杰夫,你好!
p.s. Hi Jeff!
这篇关于嵌入式结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!