Go Maps: Difference between revisions
Line 76: | Line 76: | ||
More about <tt>make()</tt> is available <tt>[[Go_Maps#make.28.29|here]]</tt>. | More about <tt>make()</tt> is available <tt>[[Go_Maps#make.28.29|here]]</tt>. | ||
=<tt>nil</tt> Maps and Empty Maps= | |||
Declaring a map without initializing it creates a <tt>nil</tt> map - the map variable is initialized with <tt>nil</tt>. This is common behavior for [[Go_Concepts_-_The_Type_System#Reference_Types|reference types]]: | |||
<pre> | |||
var m map[string]string | |||
</pre> | |||
For a <tt>nil</tt> slice, <tt>fmt.Printf("%p", s)</tt> prints <tt>0x0</tt>. The underlying data structures are initialized as follows: the array pointer is initialized to <tt>nil</tt>, the length is initialized to 0 and the capacity is initialized to 0. | |||
A <tt>nil</tt> slice is different from an ''empty'' slice: | |||
<pre> | |||
s := []int{} | |||
</pre> | |||
<pre> | |||
s := make([]int, 0) | |||
</pre> | |||
For an empty slice, <tt>fmt.Printf("%p", s)</tt> prints a pointer: <tt>0x19d730</tt>. An empty slice points to a zero length array. The length is initialized to 0 and the capacity is initialized to 0. | |||
Regardless of whether a <tt>nil</tt> or empty slice is used, the built-in functions <tt>append()</tt>, <tt>len()</tt> and <tt>cap()</tt> work the same. | |||
=Map Operators and Functions= | =Map Operators and Functions= |
Revision as of 18:00, 12 April 2016
External
- Go Specification - Deletion of Map elements https://golang.org/ref/spec#Deletion_of_map_elements
Internal
Overview
A map is an unordered collection of key-value pairs. The map implementation uses the key as an index, quickly retrieving the associated value.
The map key can be a value from any built-in or struct type as long as the value can be used in an expression with an == operator. Slices, functions and struct types that contain slices can't be used as map keys, an attempt will generate a compiler error.
Lexically, a map type is a reference type. The map instances must be initialized before attempting to use into them, either by using the make() function or a map literal, otherwise you will get a runtime error, because a zero value for a map is nil:
panic: assignment to entry in nil map
Implementation Details
In order to store a key/value pair in the map, the map hash function is applied to the key, which produces the index of a bucket. The purpose of the hash function is to generate the index that is evenly distributed across the bucket population. Once a bucket is selected, the map stores the key/value pair in the bucket.
In order to retrieve the value corresponding to a key, the same hash function is applied to select the bucket, and then the map iterates over the keys stored in that bucket.
Declaration
Long Declaration
var map_identifier map[key_type]value_type
Example of a map of string to ints:
var m map[string]int
A map declaration and initialization with a map literal:
var m map[string]string = map[string]string { "A": "B", "C": "D", }
A map declaration and initialization with make():
var m map[string]string = make(map[string]string)
Short Declaration
Short Declaration with Literals
m := map[string]string { "A": "B", "C": "D", }
Using a literal is the idiomatic way to create a map.
Short Declaration with make()
m := make(map[string]string)
More about make() is available here.
nil Maps and Empty Maps
Declaring a map without initializing it creates a nil map - the map variable is initialized with nil. This is common behavior for reference types:
var m map[string]string
For a nil slice, fmt.Printf("%p", s) prints 0x0. The underlying data structures are initialized as follows: the array pointer is initialized to nil, the length is initialized to 0 and the capacity is initialized to 0.
A nil slice is different from an empty slice:
s := []int{}
s := make([]int, 0)
For an empty slice, fmt.Printf("%p", s) prints a pointer: 0x19d730. An empty slice points to a zero length array. The length is initialized to 0 and the capacity is initialized to 0.
Regardless of whether a nil or empty slice is used, the built-in functions append(), len() and cap() work the same.
Map Operators and Functions
Indexing Operator
Assigning a key/value pair to the map is performed using the indexing [] and the assignment operators =:
m["something"] = "something else"
Indexing operator [] returns the copy of the value corresponding to the specified key and a boolean value that says whether the key exists or not. If the key does not exist, the zero value for the value type is returned.
value := m["key"] // only the first return value can be used, as long as we are prepared to deal with the zero value value, exists := m["key"]
Idiom:
if value, exists := m["key"]; exists { // it exists ... }
Map Length
len() returns the number of keys.
delete()
Removes the element corresponding to the given key from the map:
delete(m, "something")
It is a no-op if the key does not exist.
make()
The make() function creates the map:
m := make(map[key_type]value_type)
Note that make() returns the map instance, not a pointer.