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

时间:2017-07-31 17:49:43

标签: go

type a struct{}

type b *a
type c a

func main() {
    var _ b = &a{}
    var _ c = a{}
}

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

3 个答案:

答案 0 :(得分:5)

根据go spec

  

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

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

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

  

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

基本上,您可以将命名类型视为可以仅表示为由点分隔的标识符或标识符的任何类型。例如,fooFoo.Bar

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

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

答案 1 :(得分:3)

根据规范,在assignability部分,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类型的变量,因为它不满足任何条件及其基础类型({{1 }}和a)不一样。

答案 2 :(得分:0)

正如已经提到的,它是关于未命名类型的可分配性,而不是指针。

var _ c = struct{}{} //same as a{} but unnamed

编译。