【发布时间】:2015-04-13 05:00:32
【问题描述】:
type (
A struct {
a string
}
B struct {
b *A.a
}
)
我收到此错误:
A.a undefined (type A has no method a)
我在这里遗漏了什么吗?还是 Go 中不允许?
【问题讨论】:
type (
A struct {
a string
}
B struct {
b *A.a
}
)
我收到此错误:
A.a undefined (type A has no method a)
我在这里遗漏了什么吗?还是 Go 中不允许?
【问题讨论】:
定义结构字段时,必须指定its name and its type,就像使用结构A.a 一样。但是在结构B:
b *A.a
*A.a 不是类型。
您不能将struct 的字段嵌入到另一个结构中。请注意,您可以通过省略 name 部分将 complete 结构嵌入到另一个结构中,如下所示:
type (
A struct {
a string
}
B struct {
A
}
)
结果是A 类型的所有字段和方法也将成为结构B 的成员。如果需要B的内嵌结构体A,可以通过引用类型名来访问:
var b B
fmt.Println(b.A)
您可以做的另一件事是在B 中有一个字段,它是一个指针,它指向A 类型的现有值 的字段:
B struct {
ap *string
}
a := A{a:"test"}
b := B{ap:&a.a} // B.ap will point to a.a
fmt.Println(*b.ap) // Prints "test"
【讨论】:
问题是您使用*A.a 作为字段b 的类型说明符。您唯一缺少的是您应该在那里拥有b string 或b *string(如果您至少想要结构B 中的字符串字段)。
现在,如果您的目标是更类似于“继承”该字段,那么您应该嵌入A 到B 中,这将为B 提供一个名为a 的属性。看起来像这样;
type B struct {
A
}
这是与 Go 提供的继承最相似的构造。如果您要嵌入此处,则可以执行以下操作;
var instanceOfB = &B{}
fmt.Println(instanceOfB.a)
这在功能上等同于让 B 从 A 继承(在这种情况下,尽管两者并不相同,而且许多行为也不同。我只是认为比较/对比继承很有帮助)。此时,您可以直接从B 的实例访问A 上的属性或方法。最好避免名称冲突,尽管它们不会导致编译器错误。如果您确实在嵌入式类型或嵌入器和嵌入式类型之间存在命名冲突,则在运行时决定使用哪个方法/属性,我不确定解析规则是什么,但我认为您可以在语言中找到它们规格。
现在我的最后一个想法...如果您的目标是从B 的某个实例中引用A 实例中的a 属性,您只需在B 中包含一个刺指针并设置当您实例化B 时,它在构造函数中的&A.a 是一个静态初始化器。然而,这可能是一种不好的做法,因为它违反了封装的概念,而且很明显容易出错。
【讨论】: