Hacker News new | ask | show | jobs
by shazow 3948 days ago
> Here's a trick that I expected to work but doesn't. Would be interested to hear the rationale if anyone knows it.

    m := map[[]int]int{}
... will not work, because []int is a slice—that is, a pointer to an array of undetermined state (also technically some more metadata like an offset/size). Think of a slice as a "view" into an array, which does not necessarily need to remain static. A slice does not necessarily "own" the data it's providing a view of; you can have many slices of one array.

    m := map[[3]int]int{}
will work, because [3]int is an actual array.

To recap:

    a := [3]int{1,2,3}  // Array
    b := a[:2]          // Slice
    var c []int = a[:]  // Slice
    var d [3]int        // Array
    copy(d[:], c)       // Copy to (a slice of an) array from slice
1 comments

Well, you could take the position that types that permit modification should not be allowed as keys but then you would not allow arrays as keys, which Go does allow. Check this out: http://play.golang.org/p/kocW1BjTco

Another approach to take, which I think could be quite useful, is that if you use something modifiable as a key, then the map takes a snapshot of it when you perform the insert. That way, I can go and modify the key after the insert and any time thereafter if I look for the same sequence of integers, the map will find the associated value.

The problem here is that, in a language like Go, where pointer values are significant (contrast with Haskell, where two lists allocated separately but having the same contents are indistinguishable), you sometimes want to use pointer identity as the key so maybe it's hard to have it both ways.

Oh well. It's just something that surprises someone like me, who has grown accustomed to more value-oriented languages.