Are maps passed by value or reference in Go ?
It is always possible to define a function as following, but is this an overkill ?
func foo(dat *map[string]interface{}) {...}
Same question for return value. Should I return a pointer to the map, or return the map as value ?
The intention is of course to avoid unnecessary data copy.
In this thread you will find your answer :
Golang: Accessing a map using its reference
You don't need to use a pointer with a map.
Map types are reference types, like pointers or slices[1]
If you needed to change the Session you could use a pointer:
map[string]*Session
No Maps are reference by default.
package main
import "fmt"
func mapToAnotherFunction(m map[string]int) {
m["hello"] = 3
m["world"] = 4
m["new_word"] = 5
}
// func mapToAnotherFunctionAsRef(m *map[string]int) {
// m["hello"] = 30
// m["world"] = 40
// m["2ndFunction"] = 5
// }
func main() {
m := make(map[string]int)
m["hello"] = 1
m["world"] = 2
// Initial State
for key, val := range m {
fmt.Println(key, "=>", val)
}
fmt.Println("-----------------------")
mapToAnotherFunction(m)
// After Passing to the function as a pointer
for key, val := range m {
fmt.Println(key, "=>", val)
}
// Try Un Commenting This Line
fmt.Println("-----------------------")
// mapToAnotherFunctionAsRef(&m)
// // After Passing to the function as a pointer
// for key, val := range m {
// fmt.Println(key, "=>", val)
// }
// Outputs
// prog.go:12:4: invalid operation: m["hello"] (type *map[string]int does not support indexing)
// prog.go:13:4: invalid operation: m["world"] (type *map[string]int does not support indexing)
// prog.go:14:4: invalid operation: m["2ndFunction"] (type *map[string]int does not support indexing)
}
From Golang Blog-
Map types are reference types, like pointers or slices, and so the value of m above is nil; it doesn't point to an initialized map. A nil map behaves like an empty map when reading, but attempts to write to a nil map will cause a runtime panic; don't do that. To initialize a map, use the built in make function:
m = make(map[string]int)
Code Snippet Link Play with it.
Here are some parts from If a map isn’t a reference variable, what is it? by Dave Chaney:
A map value is a pointer to a runtime.hmap structure.
and conclusion:
Conclusion
Maps, like channels, but unlike slices, are just pointers to runtime types. As you saw above, a map is just a pointer to a runtime.hmap structure.
Maps have the same pointer semantics as any other pointer value in a Go program. There is no magic save the rewriting of map syntax by the compiler into calls to functions in runtime/hmap.go.
And an interesting bit about history/explanation of map
syntax:
If maps are pointers, shouldn’t they be *map[key]value?
It’s a good question that if maps are pointer values, why does the expression make(map[int]int) return a value with the type map[int]int. Shouldn’t it return a *map[int]int? Ian Taylor answered this recently in a golang-nuts thread1.
In the very early days what we call maps now were written as pointers, so you wrote *map[int]int. We moved away from that when we realized that no one ever wrote
map
without writing*map
.Arguably renaming the type from *map[int]int to map[int]int, while confusing because the type does not look like a pointer, was less confusing than a pointer shaped value which cannot be dereferenced.