Почему я не могу инициализировать карту с помощью new () в Go? - PullRequest
0 голосов
/ 16 декабря 2018
package main

import "fmt"

func main() {
    p := new(map[string]int)
    m := make(map[string]int)
    m["in m"] = 2
    (*p)["in p"] = 1
    fmt.Println(m)
    fmt.Println(*p)
}

Приведенный выше код выдает ошибку panic: assignment to entry in nil map.Если я напечатаю *p перед тем, как вставить в него пары, вывод будет правильным.Кажется, я просто не могу изменить *p?

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

Это напрямую не связано с ключевым словом new.Вы бы получили то же поведение, если бы не инициализировали свою карту при объявлении ее с помощью ключевого слова var, например:

var a map[string]int
a["z"] = 10

Чтобы исправить это, нужно инициализировать карту:

var a map[string]int
a = map[string]int{}
a["z"] = 10

И работает точно так же с ключевым словом new:

p := new(map[string]int)
*p = map[string]int{}
(*p)["in p"] = 1 

Причина, по которой make(map[string]int) делает то, что вы ожидаете, заключается в том, что карта объявлена ​​и инициализирована.

Игровая площадка Go

0 голосов
/ 16 декабря 2018

Оба new и make используются для выделения памяти в программе, но они работают по-разному.new(T, args) обнуляет память и возвращает адрес памяти (значение типа *T), но не инициализирует эту память.make(T, args), с другой стороны, инициализирует значение типа T.Карту необходимо инициализировать, поскольку, хотя карта может быть пустой, структура самой карты по-прежнему имеет ненулевую структуру, поэтому ее необходимо инициализировать перед использованием.

С ДействуетGo :

Встроенная функция make (T, args) служит цели, отличной от новой (T).Он создает только срезы, карты и каналы и возвращает инициализированное (не обнуленное) значение типа T (не * T).Причина различия заключается в том, что эти три типа представляют под крышками ссылки на структуры данных, которые должны быть инициализированы перед использованием.Например, срез - это трехэлементный дескриптор, содержащий указатель на данные (внутри массива), длину и емкость, и до тех пор, пока эти элементы не будут инициализированы, срез будет равен нулю.Для срезов, карт и каналов make инициализирует внутреннюю структуру данных и подготавливает значение для использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...