Home > Back-end >  first argument to append must be a slice; have untyped nil
first argument to append must be a slice; have untyped nil

Time:06-19

I'm a newbie Go programmer confused by the below behaviour. I expected the program to fail at t2 with error

first argument to append must be a slice; have untyped nil

but Go is happy when passing in nil as first parameter to append when it's a parameter to a method?

package main

import "fmt"

type Thing struct {
    data []string
}

func NewThing(extra []string) Thing {
    return Thing{
        data: append(extra, "b"),
    }
}

func main() {
    t := NewThing([]string{"a"})
    fmt.Println(t.data) // [a b]

    t2 := NewThing(nil)
    fmt.Println(t2.data) // [b]

    //_ = Thing{ // build failed: first argument to append must be a slice; have untyped nil
    //  data: append(nil, "b"),
    //}
}

Playground: https://go.dev/play/p/Cxi7fRHu3Wi

Is this just a convenience feature or am I understanding this wrong?

CodePudding user response:

It is a convenience that the capacity and length of a nil slice is zero. From there, append works as normal when passed a nil slice.

The call append(nil, "b") does not compile because nil has no type. The compiler cannot determine the type of the result because the slice argument does not have a type.

The call append(extra, "b") works when extra is nil because extra is a typed value (a []string). Given the slice type, the compiler knows that the result is []string and that the appended elements must be assignable to string.

The call append([]string(nil), "b") also works because the expression []string(nil) is a typed value.

  • Related