maps.Keys() does not work when keys are of type language.Tag

154 views
Skip to first unread message

Jochen Voss

unread,
Oct 6, 2022, 7:29:46 AM10/6/22
to golang-nuts
Hello,

Using "golang.org/x/text/language" I have a map of type map[language.Tag]int.  I would like to get the keys present in my map.  Why does the following command not work?

    import "golang.org/x/exp/maps"
    ...
    var x map[language.Tag]int
    ...
    fmt.Println(maps.Keys(x))

The error message is "Tag does not implement comparable".  Code on the playground: https://go.dev/play/p/dsyEt0ClDBH .

The following function does work as expected, so this is easy to work around:

    func myKeys(m map[language.Tag]int) []language.Tag {
        var res []language.Tag
        for key := range m {
            res = append(res, key)
        }
        return res
    }

But I wonder now whether it is unwise to use language.Tag for the keys in a map, and why maps.Keys() requires the keys to implement "comparable" in addition to the constraint "M ~map[K]V".

Many thanks,
Jochen




jake...@gmail.com

unread,
Oct 6, 2022, 9:29:12 AM10/6/22
to golang-nuts
It appears to be because, deep down, the language.Tag struct contains an interface. While interfaces are "comparable", in that you can use == & !=, apparently they do not implement the  'comparable' constraint.

I'm not sure why this decision was made, though I can guess. There is probably discussion about it somewhere. It does seem to me that this should be documented the  'comparable' constraint documentation. It also makes me wonder if there are other cases where '==' compiles, but the types are not 'comparable'.

Ian Lance Taylor

unread,
Oct 6, 2022, 4:46:09 PM10/6/22
to Jochen Voss, golang-nuts
There is a lot of discussion about this at places like
https://go.dev/issue/51338 and https://go.dev/issue/52509 and others.
It remains an open topic.

Ian
Reply all
Reply to author
Forward
0 new messages