первое отличие:
Встроенная функция нового принимает тип Т, выделяет память для переменной этого типа во время выполнения
2 разница: new
инициализирует выделенную строку пустой строкой ("") и инициализирует указатель на a ddress этой строки, но var ptr2 *string
просто инициализирует ptr2
к nil
и не выделяет любую строку:
образец кода A (с комментариями выход):
ptr := new(string) // *ptr has value "", ptr: static type *string
fmt.Println(len(*ptr)) // 0
fmt.Println(cap([]byte(*ptr))) // 32
fmt.Printf("%T %q\n", ptr, *ptr) // *string ""
образец кода B (с комментариями выход):
var ptr2 *string // ptr2 has value nil, static type *string
fmt.Printf("%T %#[1]v\n", ptr2) // *string (*string)(nil)
//fmt.Println(len(*ptr2)) // panic: runtime error: invalid memory address or nil pointer dereference
//fmt.Println(cap([]byte(*ptr2)))
образец кода с (с комментариями выход):
var str string // str has value "", static type string
fmt.Println(len(str)) // 0
fmt.Println(cap([]byte(str))) // 32
fmt.Printf("%T %[1]q\n", str) // string ""
Распределение:
Встроенная функция нового принимает тип Т, выделяет память для переменной этого типа во время выполнения, и возвращает значение типа * T указывая на него. Переменная инициализируется, как описано в разделе на initial values.
new(T)
Например
type S struct { a int; b float64 }
new(S)
выделяет память для переменной типа S, инициализирует его (а = 0, Ь = 0,0), и возвращает значение типа * S, содержащий адрес .
исх: https://golang.org/ref/spec
Allocation с новым:
Go имеет два примитива распределения, встроенный в функции новых и сделать. Они делают разные вещи и применяют к разные типы, которые могут ввести в заблуждение, но правила просты. Давайте поговорим о новых первых. Это встроенная функция, которая выделяет память, но в отличие от своих однофамильцев на некоторых других языках она не инициализирует память, она только нулирует ее. То есть новый (T) выделяет обнуленное хранилище для нового элемента типа T и возвращает его адрес, значение типа * T. В терминологии Go, он возвращает указатель на вновь выделяемых нулевого значение типа T.
Поскольку память возвращаемой новым обнуляются, полезно организовать при проектировании ваших структур данных, что нулевое значения каждого типа можно использовать без дальнейшей инициализации. Это означает, что пользователь структуры данных может создать новую и получить право на работу. Например, для документации для байтов. Буффер утверждает, что «значение нулевого значения для буфера - это пустой буфер, готовый к использованию». Аналогично, sync.Mutex не имеет явного конструктора или метода Init. Вместо этого нулевое значение для sync.Mutex определяется как разблокированный мьютекс .
Объект с нулевым значением полезен транзитивно. Рассмотрим это объявление типа .
type SyncedBuffer struct {
lock sync.Mutex
buffer bytes.Buffer
} Values of type SyncedBuffer are also ready to use immediately upon allocation or just declaration. In the next snippet, both p and v
будет корректно работать без дополнительной договоренности:
p := new(SyncedBuffer) // type *SyncedBuffer
var v SyncedBuffer // type SyncedBuffer
Распределение с замыкающими: Назад к распределению. Встроенная функция make (T, args) отличается от новой (T). Он создает только фрагменты, карты и каналы и возвращает инициализированное (не ) значение типа T (not * T). Причиной отличия является , что эти три типа представляют под крышками ссылки на данные структуры, которые должны быть инициализированы перед использованием. Например, фрагмент, например, , представляет собой трехпозиционный дескриптор, содержащий указатель на данные (внутри массива ), длину и емкость, и до тех пор, пока эти элементы не будут инициализированы, срез равен нулю. Для фрагментов, карт и каналов make инициализирует внутреннюю структуру данных и подготавливает значение для использования . Например,
make([]int, 10, 100)
выделяет массив из 100 целых чисел, а затем создает структуру среза с длиной 10 и мощностью 100 указывая на первых 10 элементов массива. (При создании фрагмента емкость может быть опущена, см. Раздел на фрагментах для получения дополнительной информации о .) Напротив, новый ([] int) возвращает указатель на недавно выделенную, обрезанную структуру среза, указатель на нулевой фрагмент значение.Эти примеры иллюстрируют разницу между новым и сделать:
var p *[]int = new([]int) // allocates slice structure; *p == nil; rarely useful
var v []int = make([]int, 100) // the slice v now refers to a new array of 100 ints
// Unnecessarily complex:
var p *[]int = new([]int)
*p = make([]int, 100, 100)
// Idiomatic:
v := make([]int, 100)
Помните, что делает распространяется только на карты, ломтики и каналы и не не возвращает указатель. Чтобы получить явный указатель, выделите его с помощью нового или явно введите адрес переменной.
исй: https://golang.org/doc/effective_go.html
новые выделяет память динамически, для неинициализированной переменной памяти еще не выделен. – ShivBuyya
Это адрес памяти или содержимого памяти? потому что, если я проверяю адрес обоих, они выделяются. Содержание также. –