How to create generic method in Go? (method must have no type parameters)

You have to declare the slice type with type parameters you want to use for the Map() (or for any other) method:

type slice[E, V any] []E

And you have to add the type parameters to the receiver, without the constraints (those will be the same as defined at the type declaration), as if you’d instantiate the generic slice type:

func (s *slice[E, V]) Map(iteratee func(E) V) *[]V {
    result := []V{}
    for _, item := range *s {
        result = append(result, iteratee(item))
    }

    return &result
}

Testing it:

s := slice[int, string]{1, 2, 3}
m := s.Map(func(i int) string { return fmt.Sprint("x", i) })
fmt.Println(m)

Which will output (try it on the Go Playground):

&[x1 x2 x3]

Also note that slices (slice headers) already contain a pointer to an underlying array, so it’s rare that you need to use a pointer to slice. Instead declare the method with non-pointer receiver, and return a non-pointer (try this one on the Go Playground):

func (s slice[E, V]) Map(iteratee func(E) V) []V {
    result := []V{}
    for _, item := range s {
        result = append(result, iteratee(item))
    }

    return result
}

Relevant section from the (tip) spec: Spec: Method declarations:

If the receiver base type is a parameterized type, the receiver specification must declare corresponding type parameters for the method to use. This makes the receiver type parameters available to the method.

Syntactically, this type parameter declaration looks like an instantiation of the receiver base type, except that the type arguments are the type parameters being declared, one for each type parameter of the receiver base type. The type parameter names do not need to match their corresponding parameter names in the receiver base type definition, and all non-blank parameter names must be unique in the receiver parameter section and the method signature. The receiver type parameter constraints are implied by the receiver base type definition: corresponding type parameters have corresponding constraints.

Leave a Comment