Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Complex datatypes as keys in maps in Go

Tags:

go

I'm trying to create a map in Go that is keyed by big integers. Effective Go explicitly says that:

Structs, arrays and slices cannot be used as map keys, because equality is not defined on those types.

which makes sense. I could of course convert the big integers to strings and use the string as a key, but I'm looking for a more general solution here. Can I wrap my structure into something (an interface?) that implements an equality function and use that instead?

Example code that, of course, doesn't work:

package main                                                                                                           

import (                                                                                                               
        "big"                                                                                                          
        "fmt"                                                                                                          
)                                                                                                                      

func main() {                                                                                                          
        one1 := big.NewInt(1)                                                                                          
        one2 := big.NewInt(1)                                                                                          

        hmap := make(map[*big.Int] int)                                                                                
        hmap[one1] = 2                                                                                                 
        _, exists := hmap[one2]                                                                                        
        fmt.Printf("Exists=%v\n", exists)                                                                              
}                                                                                                                      
like image 721
Olof Avatar asked Nov 09 '11 20:11

Olof


1 Answers

The rules about equality are going to change soon. From the Go 1 plan:

Go 1 will define equality on struct and array values composed from fields on which equality is also defined (element-wise comparison). It will remove equality on function and map values except for comparison with nil. Go 1 will continue to exclude equality for slices. (In the general case it is infeasible.)

However, even with this rules, you can not use *BigInt as key, since it contains a slice. Also note, that it is not possible in Go to write a custom equality operator (neither it is possible to override any other operator). But that's actually a strength of Go in my opinion - things are just simpler without it.

So, you will have to use strings for your keys. The strings however do not need to be formatted in decimal (or any other format) as long as you do not want to print them. So the fastest way is probably to use the Bytes() method (which will also discard the sign, make sure to include that separately in your string).

like image 146
tux21b Avatar answered Sep 28 '22 07:09

tux21b