有没有可能在不使用嵌入式结构的情况下继承类型的方法?
第一段代码是在Node中嵌入Property结构的工作代码,我可以调用node.GetString,这是Properties上的一个方法。我不喜欢这一点的是,当我初始化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方法。
发布于 2015-12-04 16:06:28
所以你遇到了Go here的一种特性。嵌入是一个结构的方法可以“提升”到出现在另一个结构上的唯一方法。虽然感觉type Node Properties应该在Node上公开Properties方法是很直观的,但是这种语法的效果是让Node采用Properties的内存布局,而不是它的任何方法。
它没有解释为什么做出这种设计选择,但Go Spec至少是特定的,如果是dry。如果你完全按照它的样子读,没有任何解释,它是非常准确的:
接口类型的方法集就是它的接口。任何其他类型T的方法集由用接收器类型T声明的所有方法组成
GetString有一个Properties类型的接收器,而不是Node类型,说真的,就像你是一个没有想象力的会计一样来解释这个规范。如上所述:
进一步的规则适用于包含匿名字段的结构,如结构类型部分所述。
..。
如果x.f是表示某个字段或方法f的合法选择器,则结构x中匿名字段的字段或方法f称为promoted。
提升字段的行为类似于结构的普通字段,不同之处在于它们不能用作结构的复合文本中的字段名。
给定结构类型S和名为T的类型,提升的方法包含在结构的方法集中,如下所示:
关于复合文字的这一行迫使您在创建的每个Node中声明Properties。
附注:嗨,杰夫!
发布于 2015-12-04 16:08:10
最后一个问题的简短答案是No。
在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中是不可能的,我认为你应该坚持你的第一种方法,忽略代码冗余和丑陋的事实。
https://stackoverflow.com/questions/34079466
复制相似问题