英文:
Struct embedding and ambiguity resolution
问题
在Golang的结构嵌入中,我遇到了一个歧义。嵌入的结构体有一个字段num,而容器结构体也有一个字段num。
type base struct {
num int
}
type container struct {
base
str string
num int
}
在引用时,它的解析如下,这样使用合法和正确吗?
container.num - 解析为外部
&
container.base.num - 解析为内部
英文:
In Golang structure embedding I have created an ambiguity. Embedded struct have and field num, and container struct too have a field num.
type base struct {
num int
}
type container struct {
base
str string
num int
}
While referencing, it resolved as follows, and is it legal and correct use?
container.num - resolved to outer
&
container.base.num - resolved to inner
答案1
得分: 2
嵌入类型的字段和方法会被提升,如果选择器表达式不含糊,你可以使用它。如果嵌入类型的结构体中也有与被提升的字段同名的字段,也不会有问题,但是显然container.num
不能指代两个不同的字段,只能指代其中一个。语言规范明确定义了具体指代哪个字段。规范中指出:
以下规则适用于选择器:
- 对于类型为
T
或*T
的值x
,其中T
不是指针类型或接口类型,x.f
表示在T
的最浅层次上存在f
的字段或方法。如果最浅层次上不止一个f
,则选择器表达式是非法的。
所以在你的例子中,最浅层次是container.num
,而不是container.base.num
。这里没有歧义。
再看一个例子:
type base struct {
num int
}
type base2 struct {
num int
}
type container struct {
base
base2
str string
}
container
嵌入了base
和base2
,它们都有一个名为num
的字段。同样,这种嵌入本身没有问题。你可以使用container.base.num
和container.base2.num
来引用这些字段。但是如果你写container.num
,由于在最浅层次(深度为1)上有两个被表示为container.num
的字段,选择器表达式是无效的,并且会导致编译时错误。
英文:
Embedding is never a problem. Fields and methods of the embedded type get promoted, and if the selector expression is not ambiguous, you may use it.
If the embedder type also has a field name the same as a field that could get promoted, that's also not a problem, but obviously container.num
can't designate 2 different fields, only one. The language spec properly defines what that will be. Spec: Selectors:
> The following rules apply to selectors:
> 1. For a value x
of type T
or *T
where T
is not a pointer or interface type, x.f
denotes the field or method at the shallowest depth in T
where there is such an f
. If there is not exactly one f
with shallowest depth, the selector expression is illegal.
>
> [...]
So the "shallowest" in your case is container.num
, not container.base.num
. No ambiguity here.
Let's see another example;
type base struct {
num int
}
type base2 struct {
num int
}
type container struct {
base
base2
str string
}
container
embeds base
and base2
, and both have a field named num
. Again, this embedding itself is not a problem. You can also refer to those fields using container.base.num
and container.base2.num
. But if you'd write container.num
, since there are not one (but 2) fields denoted by container.num
at the shallowest depth (depth = 1), the selector expression is invalid and would result in a compile-time error.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论