I am using custom types and I have a problem when pointers are involved like below.
Code below is valid:
package main
import (
"fmt"
)
type deck []string
func newDeck(cards ...string) deck {
return cards
}
Code below is valid too:
package main
func str(n []string) *[]string {
return &n
}
The below code instead is not valid. Why so? I have to write a type conversion like return (*deck)(&cards)
package main
import (
"fmt"
)
type deck []string
func newDeck(cards ...string) *deck {
return &cards // compiles with return (*deck)(&cards)
}
CodePudding user response:
The rules about assignments (including returns) are defined in the Go specs: Assignability. The one that is relevant to your case is:
V
andT
have identical underlying types and at least one of V or T is not a named type.
And Underlying types:
If T is one of the predeclared boolean, numeric, or string types, or a type literal, the corresponding underlying type is T itself.
The first example compiles because []string
is an unnamed type literal with underlying type []string
(itself) and deck
is a named type with underlying type []string
(by your type definition).
The second example does not compile because both *[]string
and *deck
are unnamed type literals with themselves as (different) underlying types.
To make the second example compile, you can't rely on a direct assignment, but, as you found out, use an explicit type conversion
return (*deck)(&cards)
And this conversion is valid due to the following rule:
ignoring struct tags (see below),
x
's type andT
are pointer types that are not named types, and their pointer base types are not type parameters but have identical underlying types.