Slice and map type sets for range operations

166 views
Skip to first unread message

will....@gmail.com

unread,
Apr 27, 2022, 6:56:22 PM4/27/22
to golang-nuts
Do slices and maps have compatible type sets regarding the range operator?

I was trying to iterate through either, where slice keys are the indexes, such that this would work:

type KV[K comparable, V any] interface {
    ~[]V | map[K]V
}

func f[KV2 KV[K, V], K comparable, V any](kv KV2) {
    for k, v := range kv { // line 12
        fmt.Println(k, v)
    }
}

func main() {
    f[map[string]string, string, string](map[string]string{"a": "b", "c": "d"}) // works
    f[[]string, int, string]([]string{"e", "f"}) // error
}

I get this error:

./prog.go:12:20: cannot range over kv (variable of type KV2 constrained by KV[K, V]) (KV2 has no core type)


I'm having trouble understanding this error message. Is this saying that maps and slices don't have a core type because they're not compatible for the range operator?

Ian Lance Taylor

unread,
Apr 27, 2022, 7:47:57 PM4/27/22
to will....@gmail.com, golang-nuts
Currently a for/range statement using a value whose type is a type
parameter is only permitted if the type parameter constraint gives it
a core type. Basically, a core type is an optional tilde followed by
a single type. It is not a union. See
https://go.dev/ref/spec#Core_types.

So the compiler is telling you that the type parameter KV2 has no core
type, so for/range is not permitted.

We impose this restriction to simplify the meaning of for/range, and
to avoid having to figure out what it would mean to range over a type
parameter whose constraint is []byte | map[int]string | chan float64.

It is possible that we will lift this restriction in a future release.

Ian

Will Faught

unread,
Apr 27, 2022, 9:18:44 PM4/27/22
to Ian Lance Taylor, golang-nuts
Makes sense. Thanks!
Reply all
Reply to author
Forward
0 new messages