Why can't Go slice (which is an implementation of Go arrays) be used as keys in Go maps pretty much the same way arrays can be used as keys?
相关问题
- How to get the maximum of more than 2 numbers in V
- Faster loop: foreach vs some (performance of jsper
- Convert Array to custom object list c#
- pick a random item from a javascript array
- Newtonsoft DeserializeXNode expands internal array
相关文章
- Can I run a single test in a suite?
- Numpy matrix of coordinates
- How to check if a request was cancelled
- Is it possible to implement an interface with unex
- PHP: Can an array have an array as a key in a key-
- Accessing an array element when returning from a f
- How can I convert a PHP function's parameter l
- How to make a custom list deserializer in Gson?
Here's Nigel Tao's answer from https://groups.google.com/forum/#!topic/golang-nuts/zYlx6sR4F8Y:
To answer the exact "why cant?":
Spec: Map types:
The spec does not allow key types where comparison is not defined. Spec: Comparison operators also confirms this:
For reasoning, see smarx's answer (which quotes Nigel Tao's answer). And read on.
Go's map uses a hashmap implementation. In general (regardless of the programming language) mutating a value that is used as a key in a hashmap might result in undefined (or unexpected the least) behavior. Usually the hashcode of the key is used to designate the bucket in which the value (key-value pair) is placed. If the key changes and you ask for the associated value for that key, the implementation might look in the wrong bucket (and therefore report that it can't find it) because a changed key value most likely gives a different hashcode which might designate a different bucket.
In Go slices are just descriptors to a contiguous part of an underlying array, and assigning slice values only copies these descriptors. So using a slice as key you would expect that the map implementation only copies this slice header (which is the pointer to the first referenced element in the underlying array, the length and the capacity). It would only work if hash comptation and equality would use these 3 elements and nothing else, but to us (humans, programmers) a slice means the elements that can be accessed through the slice header - which can also be modified (causing problems described above).
If a map would allow a slice as keys, to function properly, it would have to update its internal state and data structure whenever a slice element of any slice (that is used as a key) is modified which is not to be expected.
Arrays are cool in this regard: an array means all its elements; copying an array copies all the elements, and comparison is defined like:
And if you modify an element of an array that you used as a key before: not a problem as the new array (with that modified element) is not equal to the original which is stored and used in the map, so querying the associated value with the modified array will justifiably yield no results, and querying with the unmodified, original array will properly give you back the previously stored value.