Отображаются ли карты по значению или по ссылке в Go?
Отображаются ли карты по значению или ссылке в Go?
Всегда можно определить функцию как следующую, но является ли это излишним?
func foo(dat *map[string]interface{}) {...}
Тот же вопрос для возвращаемого значения. Должен ли я вернуть указатель на карту или вернуть карту в качестве значения?
Разумеется, цель состоит в том, чтобы избежать ненужной копии данных.
Ответы
Ответ 1
В этой теме вы найдете ответ:
Golang: доступ к карте с использованием ссылки
Вам не нужно использовать указатель с картой.
Типы карт являются ссылочными типами, такими как указатели или срезы [1]
Если вам нужно изменить сеанс, вы можете использовать указатель:
map[string]*Session
https://blog.golang.org/go-maps-in-action
Ответ 2
Карты не являются справочными по умолчанию.
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)
}
С Голанга Blog-
Типы карт являются ссылочными типами, такими как указатели или фрагменты, и поэтому значение m выше равно нулю; это не указывает на инициализированную карту. Нулевая карта ведет себя как пустая карта при чтении, но попытки записи на нулевую карту вызовут панику во время выполнения; не делай этого Чтобы инициализировать карту, используйте встроенную функцию make:
m = make(map[string]int)
Ссылка на фрагмент кода Играйте с ним.
Ответ 3
Вот некоторые части из Если карта не является ссылочной переменной, что это? Дэйв Чейни:
Значением карты является указатель на структуру runtime.hmap.
и вывод:
Заключение
Карты, как и каналы, но в отличие от слайсов, являются просто указателями на типы времени выполнения. Как вы видели выше, карта - это просто указатель на структуру runtime.hmap.
Карты имеют ту же семантику указателя, что и любое другое значение указателя в программе Go. Нет ничего волшебного, кроме переписывания синтаксиса карты компилятором в вызовы функций в runtime/hmap.go.
И интересная информация о синтаксической истории map
:
Если карты являются указателями, должны ли они иметь значение * map [key]?
Хороший вопрос, что если карты являются значениями указателей, почему выражение make (map [int] int) возвращает значение с типом map [int] int. Разве он не должен возвращать * map [int] int? Ян Тейлор недавно ответил на это в теме "Голанг-орех" 1.
В первые дни то, что мы сейчас называем картами, было написано как указатели, поэтому вы написали * map [int] int. Мы отошли от этого, когда поняли, что никто никогда не писал map
без написания *map
.
Возможно, переименование типа из * map [int] int в map [int] int, хотя и сбивает с толку, потому что тип не похож на указатель, было менее запутанным, чем значение в форме указателя, которое не может быть разыменовано.