Подтвердить что ты не робот

Есть ли разница между новым() и "регулярным" распределением?

В Go, есть ли заметная разница между следующими двумя сегментами кода:

v := &Vector{}

в отличие от

v := new(Vector)
4b9b3361

Ответ 1

Нет. То, что они возвращают, то же самое,

package main

import "fmt"
import "reflect"

type Vector struct {
    x   int
    y   int
}

func main() {
    v := &Vector{}
    x := new(Vector)
    fmt.Println(reflect.TypeOf(v))
    fmt.Println(reflect.TypeOf(x))
}

Результат:

*main.Vector
*main.Vector

В списке рассылки есть несколько разногласий, в которых есть оба путаницы:

https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/GDXFDJgKKSs

Одно замечание:

new() - единственный способ получить указатель на безымянное целое или другой базовый тип. Вы можете написать "p: = new (int)", но вы не можете написать "p: = & int {0}". Помимо этого, это вопрос предпочтение.

Источник: https://groups.google.com/d/msg/golang-nuts/793ZF_yeqbk/-zyUAPT-e4IJ

Ответ 2

Да, существует фундаментальное различие между двумя фрагментами кода.

v := &Vector{}

Работает только для Vector как тип структуры, тип карты, тип массива или тип среза

v := new(Vector)

Работает для Vector любого.

Пример: http://play.golang.org/p/nAHjL1ZEuu

Ответ 3

В соответствии с Эффективный ход, new() - это функция, которая выделяет память и нулевая ее; то есть каждое поле (и весь фрагмент памяти для структуры) будет установлено на 0 s. Если вы создаете свои структуры так, чтобы при их создании все поля должны были равняться нулю, чем это было хорошо и рекомендовали использовать его. Если, однако, вам нужно больше контролировать, какие исходные значения должны использоваться, тогда следует использовать более обычный метод.

В конкретном случае вы упоминаете, что разница не имеет значения, но это следует отметить в другом месте.

Надеюсь, это поможет!:)

Ответ 4

В этом примере оба эти значения будут выделены в куче. Go не похож на C, где вы можете явно определить, где выделена память. Go выполняет "анализ побега" во время компиляции и выделяет память в куче, если это необходимо. Из того, что я понимаю, если вы когда-либо ссылаетесь на адрес объекта, он будет выделен в кучу. Поскольку v := &Vector{} присваивает адрес от Vector{} до v, компилятор решит, что это нужно выделить в куче.