In Go, arrays are inflexible (because their length is encoded in their type) and costly to pass to functions (because a function operates on copies of its array arguments). I’m assuming you’d like to operate on slices rather than on arrays.
Because methods cannot take additional type arguments, you cannot simply declare a generic Map
method in Go. However, you can define Map
as a generic top-level function:
func Map[T, U any](ts []T, f func(T) U) []U {
us := make([]U, len(ts))
for i := range ts {
us[i] = f(ts[i])
}
return us
}
Then you can write the following code,
names := []string{"Alice", "Bob", "Carol"}
fmt.Println(Map(names, utf8.RuneCountInString))
which prints [5 3 5]
to stdout (try it out in this Playground).
Go 1.18 saw the addition of a golang.org/x/exp/slices
package, which provides many convenient operations on slices, but a Map
function is noticeably absent from it. The omission of that function was the result of a long discussion in the GitHub issue dedicated to the golang.org/x/exp/slices
proposal; concerns included the following:
- hidden cost (O(n)) of operations behind a one-liner
- uncertainty about error handling inside
Map
- risk of encouraging a style that strays too far from Go’s traditional style
Russ Cox ultimately elected to drop Map
from the proposal because it’s
probably better as part of a more comprehensive streams API somewhere else.