Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are map values not addressable?

Tags:

go

While playing with Go code, I found out that map values are not addressable. For example,

package main
import "fmt"

func main(){
    var mymap map[int]string = make(map[int]string)
    mymap[1] = "One"
    var myptr *string = &mymap[1]
    fmt.Println(*myptr)
}

Generates error

mapaddressable.go:7: cannot take the address of mymap[1]

Whereas, the code,

package main
import "fmt"

func main(){
    var mymap map[int]string = make(map[int]string)
    mymap[1] = "One"
    mystring := mymap[1]
    var myptr *string = &mystring
    fmt.Println(*myptr)
}

works perfectly fine.

Why is this so? Why have the Go developers chosen to make certain values not addressable? Is this a drawback or a feature of the language?

Edit: Being from a C++ background, I am not used to this not addressable trend that seems to be prevalent in Go. For example, the following code works just fine:

#include<iostream>
#include<map>
#include<string>
using namespace std;
int main(){
    map<int,string> mymap;
    mymap[1] = "one";
    string *myptr = &mymap[1];
    cout<<*myptr;
}

It would be nice if somebody could point out why the same addressability cannot be achieved (or intentionally wasn't achieved) in Go.

like image 983
Tanmay Garg Avatar asked Jul 03 '16 08:07

Tanmay Garg


2 Answers

Well I do not know about the internal Go implementation of maps but most likely it is a kind of hash table. So if you take and save the address of one of its entries and afterwards put another bunch of entries into it, your saved address may be invalid. This is due to internal reorganizations of hash tables when the load factor exceeds a certain threshold and the hash table needs to grow.
Therefore I guess it is not allowed to take the address of one of its entries in order to avoid such errors.

like image 141
DAXaholic Avatar answered Oct 30 '22 09:10

DAXaholic


Being from a C++ background.

Why are [Go] map values not addressable?


If all other languages were like C++ there would be no point in having other languages.

C++ is a complex, hard-to-read language.

Remember the Vasa! - Bjarne Stroustrup

Go, by design, is a simple, readable language.

dotGo 2015 - Rob Pike - Simplicity is Complicated


A Go map is a hash map. A deterministic hash function is applied to a map key. The hash value is used to determine the primary map bucket for the entry (key-value pair). A bucket stores one or more map entries. A primary bucket may overflow to secondary buckets. Buckets are implemented as an array. As the number of map entries increases by insertion, the hash function adapts to provide more buckets. The map entries are copied incrementally to a new, larger bucket array. If the number of map entries decreases by deletion, space may be reclaimed.

In summary, a Go map is a dynamic, self-organizing data structure. The memory address of an entry (key-value pair) is not fixed. Therefore, map values are not addressable.

GopherCon 2016 Keith Randall - Inside the Map Implementation

In Go, map value addressability is not necessary.

like image 24
peterSO Avatar answered Oct 30 '22 10:10

peterSO