Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can I directly assign an alias only when it is to a pointer?

Tags:

go

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.

like image 376
rcorre Avatar asked Jul 31 '17 17:07

rcorre


2 Answers

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.

like image 92
Stephen Weinberg Avatar answered Nov 15 '22 19:11

Stephen Weinberg


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.

like image 34
Kaveh Shahbazian Avatar answered Nov 15 '22 19:11

Kaveh Shahbazian