cobie
cobie

Reputation: 7271

Why is this struct with a map field usable as a map key in Go when the docs say it shouldn't be?

I was looking into using structs as keys in golang maps. A field in this struct is supposed to be a map also and this seems to go against the documentation provided here which says that only structs that have fields that can be compared with == and != can be in the fields of structs that are used as keys in maps. I however went ahead to try the following:

package main

import "fmt"
import "strings"

func main() {
    fmt.Println("Hello, 世界")
    fmt.Println(strings.Join([]string{"obi", "$", "56"}, ""))
    z := make(map[string]float64)

    z["obi"] = 0.003

    x := &test{
        name:"testing",
        code:z,
    }

    a := &test{
        name:"testing2",
        code:z,
    }

    y := make(map[*test] string)

    y[x] = "go home"
    y[a] = "come home"

    for key, val := range y{
        fmt.Println(key.name, key.code, val)
    }

}

type test struct{
    name string
    code map[string]float64
}

The output was:

Hello, 世界
obi$56
testing map[obi:0.003] go home
testing2 map[obi:0.003] come home

This seems to go against the documentation as a field in the struct used as a key is a map. What do I seem to be getting wrong?

Upvotes: 38

Views: 58466

Answers (2)

15412s
15412s

Reputation: 3728

only comparable type can be used as a key (== ,!=). struct (not a pointer) is comparable in case it contains only comparable types.

Upvotes: 14

andybalholm
andybalholm

Reputation: 16100

In your example the map key is a pointer to the struct, not the struct itself. Pointers can be compared for equality even when the items they point to can't be compared. This comparison is not based on the contents of the item, but only on its memory address.

Upvotes: 59

Related Questions