Отображаются ли карты по значению или по ссылке в 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, хотя и сбивает с толку, потому что тип не похож на указатель, было менее запутанным, чем значение в форме указателя, которое не может быть разыменовано.