是否可以在不使用嵌入式结构的情况下继承类型的方法?
代码的第一段是在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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")) } |
最终,我想做以下事情。其中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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 对象实例并对其进行操作的函数,而不是将其附加到该函数。 不过,这就是嵌入Go的工作方式,因此我不确定是否有解决办法。 组成,而不是继承。 - 嵌入由于某种原因被称为嵌入;)所有属性字段都嵌入到Node中。
因此,您在这里遇到了Go的特质。嵌入是一个结构中的方法可以"提升"以似乎存在于另一个结构中的唯一方法。尽管在
它没有解释为什么选择这种设计,但是Go Spec至少是特定的(如果干燥的话)。如果您完全按原样阅读它,没有任何解释,那么它是非常准确的:
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
Further rules apply to structs containing anonymous fields, as described in the section on struct types.
...
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.Given a struct type S and a type named T, promoted methods are
included in the method set of the struct as follows:
- 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.
关于复合文字的这一行迫使您在创建的每个
ps。嗨,杰夫!
- 嗨,大卫! 我想听听为什么要做出这种设计选择。 它可能在规格书中就在线条之间的深处。 希望你一切都好。
- @Jeff:这里的设计选择是Go没有继承,也没有方法重载。 嵌入只是自动委派的一种便捷方法,它具有关于选择器如何提升字段和方法的特定规则(您也可以始终直接调用它们),没有"被继承"的东西。
您最后一个问题的简短答案就是"否"。
类型声明和在golang中嵌入之间有很大的区别,您可以通过在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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中是不可能的,我认为您应该坚持第一种方法,而忽略代码是多余的事实,并且丑陋 。