I have the following code:
package main
type Vertex struct {
X, Y float64
}
type VertexPointer *Vertex
func main() {
v := Vertex{3, 4}
v_ptr := &v
var test_1 *Vertex = &v
var test_2 **Vertex = &v_ptr
var test_3 VertexPointer = &v
var test_4 *VertexPointer = &v_ptr
}
When I try and run it (I'm using Go 1.6.2) I get the following error:
# command-line-arguments
./pointers.go:17: cannot use &v_ptr (type **Vertex) as type *VertexPointer in assignment
I'm confused why the assignment involving test_3
works but not test_4
. Based on what I've been reading, my understanding is that either both assignments should work or neither of them should work. Isn't the described behaviour a bit inconsistent?
Answer
This is all "governed" by Spec: Assignability. Assigning to test_3
is covered by this:
A value
x
is assignable to a variable of typeT
("x
is assignable toT
") in any of these cases:
And none of the assignability rules cover test_4
, so it's not allowed.
The underlying type is detailed in Spec: Types:
Each type
T
has an underlying type: IfT
is one of the predeclared boolean, numeric, or string types, or a type literal, the corresponding underlying type isT
itself. Otherwise,T
's underlying type is the underlying type of the type to whichT
refers in its type declaration.
In case of test_3
:
var test_3 VertexPointer = &v
Type of test_3
is VertexPointer
(explicitly specified), type of &v
is *Vertex
. Underlying type for both are *Vertex
, and type of &v
(which is *Vertex
) is an unnamed type, so the assignment is OK. Vertex
is a named type, but derived types such as *Vertex
or []Vertex
are unnamed types.
In case of test_4
:
var test_4 *VertexPointer = &v_ptr
Type of test_4
is *VertexPointer
, type of &v_ptr
is **Vertex
because type of v_ptr
is *Vertex
, not VertexPointer
. Underlying type of test_4
is *VertexPoitner
, underlying type of &v_ptr
is **Vertex
. The underlying types do not match. So there is no assignability rule that applies, so this assignment is not OK.
See similar question: Custom type passed to function as a parameter
No comments:
Post a Comment