为什么我只能在指针上直接指定别名?

rco*_*rre 8 go

type a struct{}

type b *a
type c a

func main() {
    var _ b = &a{}
    var _ c = a{}
}
Run Code Online (Sandbox Code Playgroud)

为什么b作业有效但不是c作业?我意识到后者是可能的演员,但我想知道这个限制的原因是什么.

Ste*_*erg 5

根据go规范:

在任何这些情况下,值x可分配给类型为T的变量("x可赋予T"):

  • ...
  • x的类型V和T具有相同的基础类型,并且V或T中的至少一个不是命名类型.
  • ...

另外,关于"未命名"的定义:

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

从本质上讲,您可以将命名类型视为可以表示为仅由点分隔的标识符或标识符的任何类型.例如,foo或Foo.Bar.


在您的示例中,您始终在具有相同基础类型的变量之间进行分配.问题是至少有一种类型是"未命名".

在这种情况下,您将分配&a{}一个*a(未命名的)指定类型的变量b.这有效.但是,当您将a{}(命名类型a)分配给类型的变量时c,两者都未命名,并且您收到错误.


Kav*_*ian 2

根据规范,在可分配性部分中,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.

值&a{}不是命名类型。它是一个指向a, 的指针*a。&a{}值和类型的基础类型b都是*a指向 的指针a。&a{}因此我们可以给类型变量赋值b。

但是a{}类型的值a不能分配给类型的变量,c因为它不满足任何这些条件并且它们的基础类型(a和c)不相同。