为什么只有在给指针赋值时才能直接使用别名?

huangapple go评论161阅读模式
英文:

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中至少有一个不是命名类型。
> * ...

此外,在“未命名”一词的定义中:

> 类型确定了特定于该类型的值和操作的集合。类型可以是命名的或未命名的。命名类型由(可能是限定的)类型名称指定;使用类型字面量指定未命名类型,该类型从现有类型组成新类型。

基本上,你可以将命名类型视为仅由标识符或由点分隔的标识符表示的任何类型。例如,fooFoo.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的变量,因为它不满足这些条件之一,且它们的基础类型(ac)不相同。

英文:

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.

huangapple
  • 本文由 发表于 2017年8月1日 01:49:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/45422271.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定