[go-nuts] interface map key misbehaviour

1,687 views
Skip to first unread message

chris dollin

unread,
May 13, 2010, 8:27:35 AM5/13/10
to golang-nuts
Dear All

func main() {
    m := make(map[interface{}]interface{})
    m["key"] = 17
}

fails to compile:

invalid map index "key" - need type interface { }

GOARCH=amd64
GOOS=linux

92e9a28d5886+ tip

Replacing "key" with something of type Interface{} is OK, ie,
the 17 presents no problem.

Attempting to fix the assignment by converting the
string with a conversion function fails:

    m[interface{}("key")] = 17

syntax error: unexpected interface, expecting :

Defining

  type Any interface{}

and using

    m[Any("key")] = 17

produces

internal compiler error: typename ideal string

--
Chris "allusive" Dollin

Peter Bourgon

unread,
May 13, 2010, 8:35:55 AM5/13/10
to golang-nuts
On Thu, May 13, 2010 at 2:27 PM, chris dollin <ehog....@googlemail.com> wrote:
> func main() {
>     m := make(map[interface{}]interface{})
>     m["key"] = 17
> }
>
> fails to compile:

From Effective Go: a map's "key can be of any type for which the
equality operator is defined, such as integers, floats, strings,
pointers, and interfaces (as long as the dynamic type supports
equality). Structs, arrays and slices cannot be used as map keys,
because equality is not defined on those types."

Does interface{} define an equality operator? Alternately, can one be deduced?

chris dollin

unread,
May 13, 2010, 8:44:06 AM5/13/10
to peter....@gmail.com, golang-nuts
(a) The compiler doesn't object to the creation of the type, only the
    specific use.

(b) "(as long as the dynamic type supports equality)": "key" is a string, and
    strings support equality.

(c) An example which I seem to have omitted has "key" converted to
    an interface{} and used as the key, where "used" includes successful
    map lookups.

(d) Whatever the status of having maps with interface{} keys, the
    internal error & unexpected interface deserve some analysis.

--
Chris "allusive" Dollin

roger peppe

unread,
May 13, 2010, 8:47:44 AM5/13/10
to chris dollin, peter....@gmail.com, golang-nuts
this is a compiler bug.
if you do:

var s interface{} = "key"
m[s] = 17

then it works fine.
you should raise an issue.

chris dollin

unread,
May 13, 2010, 8:58:32 AM5/13/10
to roger peppe, peter....@gmail.com, golang-nuts
On 13 May 2010 13:47, roger peppe <rogp...@gmail.com> wrote:
this is a compiler bug.
if you do:

var s interface{} = "key"
m[s] = 17

then it works fine.
you should raise an issue.

Done, ta.

--
Chris "allusive" Dollin

Peter Bourgon

unread,
May 13, 2010, 9:28:11 AM5/13/10
to golang-nuts
On Thu, May 13, 2010 at 2:44 PM, chris dollin <ehog....@googlemail.com> wrote:
> (b) "(as long as the dynamic type supports equality)": "key" is a string,
> and
>     strings support equality.

Yes, but (for my own edification) don't both string and int satisfy
interface{}, and what is the result of string == int?

> (d) Whatever the status of having maps with interface{} keys, the
>     internal error & unexpected interface deserve some analysis.

No doubt, as Roger found already.

chris dollin

unread,
May 13, 2010, 9:43:41 AM5/13/10
to peter....@gmail.com, golang-nuts
On 13 May 2010 14:28, Peter Bourgon <peterb...@gmail.com> wrote:
On Thu, May 13, 2010 at 2:44 PM, chris dollin <ehog....@googlemail.com> wrote:
> (b) "(as long as the dynamic type supports equality)": "key" is a string,
> and
>     strings support equality.

Yes, but (for my own edification) don't both string and int satisfy
interface{}, and what is the result of string == int?

Of the top of my head, I'd say that, for Go, if the types are different, the
values are not equal. But I'd not guarantee to be able to find documentation
to that effect.

--
Chris "allusive" Dollin

roger peppe

unread,
May 13, 2010, 9:51:41 AM5/13/10
to chris dollin, peter....@gmail.com, golang-nuts
On 13 May 2010 14:43, chris dollin <ehog....@googlemail.com> wrote:
>> Yes, but (for my own edification) don't both string and int satisfy
>> interface{}, and what is the result of string == int?
>
> Of the top of my head, I'd say that, for Go, if the types are different, the
> values are not equal. But I'd not guarantee to be able to find documentation
> to that effect.

from http://golang.org/doc/go_spec.html#Comparison_compatibility:

"Interface values may be compared if they have compatible static types.
They will be equal only if they have the same dynamic type and the
underlying values are equal."

so the result of string == int is false.

chris dollin

unread,
May 13, 2010, 9:53:24 AM5/13/10
to roger peppe, peter....@gmail.com, golang-nuts
Thanks, Roger.

(Hacking Java over here now.)

--
Chris "allusive" Dollin

Peter Bourgon

unread,
May 13, 2010, 9:55:41 AM5/13/10
to golang-nuts
On Thu, May 13, 2010 at 3:51 PM, roger peppe <rogp...@gmail.com> wrote:
> "Interface values may be compared if they have compatible static types.
> They will be equal only if they have the same dynamic type and the
> underlying values are equal."
>
> so the result of string == int is false.

I don't know; from the first sentence, I read that as the result of
string == int is undefined... am I wrong?

roger peppe

unread,
May 13, 2010, 10:00:35 AM5/13/10
to peter....@gmail.com, golang-nuts
the static type of an interface is the type it's declared as.

so, given:
var x, y interface{}
var z io.Reader

x == y is valid, but x == z is invalid because interface{}
is not the same type as io.Reader, even though they
are both interface types, and both may hold the same underlying
(dynamic) type.
Reply all
Reply to author
Forward
0 new messages