英文:
Why can I directly assign an alias only when it is to a pointer?
问题
type a struct{}
type b *a
type c a
func main() {
var _ b = &a{}
var _ c = a{}
}
为什么b
的赋值是有效的,而c
的赋值不是有效的?我知道后者可以通过类型转换实现,但我想知道这个限制的原因是什么。
英文:
type a struct{}
type b *a
type c a
func main() {
var _ b = &a{}
var _ c = a{}
}
Why is the b
assignment valid but not the c
assignment? I realize the latter is possible with a cast, but I'm wondering what the reasoning for this restriction is.
答案1
得分: 5
根据go规范:
> 在以下任何情况下,值x都可以分配给类型为T的变量(“x可以分配给T”):
>
> * ...
> * x的类型V和T具有相同的基础类型,并且V或T中至少有一个不是命名类型。
> * ...
此外,在“未命名”一词的定义中:
> 类型确定了特定于该类型的值和操作的集合。类型可以是命名的或未命名的。命名类型由(可能是限定的)类型名称指定;使用类型字面量指定未命名类型,该类型从现有类型组成新类型。
基本上,你可以将命名类型视为仅由标识符或由点分隔的标识符表示的任何类型。例如,foo
或Foo.Bar
。
在你的示例中,你总是在具有相同基础类型的变量之间进行赋值。问题在于涉及的类型中是否至少有一个是“未命名”的。
在这种情况下,你将&a{}
(一个*a
,未命名)分配给命名类型b
的变量。这是有效的。然而,当你将a{}
(命名类型a
)分配给类型为c
的变量时,两者都不是未命名的,所以会出现错误。
英文:
According to the go spec:
> A value x is assignable to a variable of type T ("x is assignable to T") in any of these cases:
>
> * ...
> * x's type V and T have identical underlying types and at least one of V or T is not a named type.
> * ...
Also, on the definition of "unnamed":
>A type determines the set of values and operations specific to values of that type. Types may be named or unnamed. Named types are specified by a (possibly qualified) type name; unnamed types are specified using a type literal, which composes a new type from existing types.
Essentially, you can think of a named type as any type that can be represented as just an identifier or identifiers separated by dots. For example, foo
or Foo.Bar
.
In your example, you are always assigning between variables with the same underlying type. The issue is whether at least one of the types involved is "unnamed".
In this case, you are assigning &a{}
, which is a *a
(unnamed) to a variable of named type b
. This works. However when you assign a{}
(named type a
) to a variable of type c
, neither is unnamed and you get an error.
答案2
得分: 2
根据规范,在可赋值性部分中,"值x可赋值给类型T(即'x可赋值给T')... x的类型V和T具有相同的基础类型,并且V或T中至少有一个不是命名类型"。
值&a{}
不是一个命名类型。它是指向a
的指针,表示*a
。值&a{}
和类型b
的基础类型都是*a
,指向a
的指针。因此,我们可以将值&a{}
赋给类型为b
的变量。
但是,类型为a
的值a{}
不能赋给类型为c
的变量,因为它不满足这些条件之一,且它们的基础类型(a
和c
)不相同。
英文:
According to the spec, in the assignability part, a value x is assignable to a variable of type T ("x is assignable to T") ... x's type V and T have identical underlying types and at least one of V or T is not a named type
.
Value &a{}
is not a named type. It's a pointer to a
, means *a
. The underlying type of both value &a{}
and type b
is *a
, pointer to a
. Hence we can assign value &a{}
to a variable of type b
.
But value a{}
which type's is a
, can not be assigned to a variable of type c
because it does not fulfill any of those conditions and their underlying types (a
and c
) are not the same.
答案3
得分: 0
如前所述,这是关于未命名类型的可分配性,而不是指针。
var _ c = struct{}{} //与 a{} 相同,但未命名
编译通过。
英文:
As already mentioned it's about assignability of unnamed types, not about a pointers.
var _ c = struct{}{} //same as a{} but unnamed
compiles.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论