Search code examples
gopointersvariable-assignmentuser-defined-types

Go assignment involving pointers to custom types


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)
}

Solution

  • The rules about assignments (including returns) are defined in the Go specs: Assignability. The one that is relevant to your case is:

    V and T 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 and T are pointer types that are not named types, and their pointer base types are not type parameters but have identical underlying types.