是否可以在不使用嵌入式结构的情况下继承类型的方法?
第一段代码是工作代码,它将Property
结构嵌入Node
,我可以调用node.GetString
Properties
{{1} }}。我不喜欢这件事是我初始化Node
我有(?)初始化其中的Properties
结构。有没有解决的办法?
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
结构。以下代码不起作用,但可能清楚我的目标是什么。
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
,我发现将相同的方法添加到嵌入Properties
我想更准确的问题,我想使用Node
中的Properties
方法而无需初始化number
。
答案 0 :(得分:3)
所以你遇到了Go在这里的特质。嵌入是一个结构的方法可以被“提升”出现在另一个结构上的唯一方法。虽然type Node Properties
应该在Properties
上公开Node
方法感觉很直观,但该语法的效果是Node
采用Properties
的内存布局但不是任何方法。
它没有解释为什么要做出这种设计选择,但Go Spec至少在干燥的情况下是特定的。如果您完全按原样阅读,没有解释,则非常准确:
接口类型的方法集是它的接口。任何其他类型T的方法集由声明的所有方法组成 接收器类型为T
GetString
有一个类型为Properties
而不是Node
的接收器,严肃地说,就像你是一个没有想象力的会计师那样解释规范。随着说:
其他规则适用于包含匿名字段的结构,如结构类型一节中所述。
...
如果x.f是表示该字段或方法f的合法选择器,则会调用struct x中匿名字段的字段或方法f。
提升字段的作用类似于结构的普通字段,但它们除外 不能在结构的复合文字中用作字段名称。
给定结构类型S和名为T的类型,提升的方法是 包含在结构的方法集中,如下所示:
- 如果S包含匿名字段T,则方法设置为S和* S. 包括与接收器T的推广方法。* S的方法集也 包括带接收器* T的推广方法。
- 如果S包含匿名 field * T,S和* S的方法集都包括提升方法 接收器T或* T。
关于复合文字的这一行强迫你在你创建的每个Properties
内声明Node
。
P.S。嗨杰夫!
答案 1 :(得分:1)
对上一个问题的简短回答只是否。
golang中的类型声明和嵌入之间存在很大差异,您可以通过在Node
和Properties
之间手动进行类型转换来使上一个示例正常工作:
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(Properties(*singleNode).GetString("test")) // :D
}
但显然这不是你想要的,你想要一个带有类型别名的语法的结构嵌入,这在golang中是不可能的,我认为你应该坚持你的第一种方法并忽略代码冗余和丑陋的事实。