왜 내가 () 또는 new ()를 만들 것입니까? 할애 new()하고 make()있지만,

도입 문서 사이의 차이를 설명하는 많은 단락을 할애 new()하고 make()있지만, 실제로는, 당신은 지역의 범위 내에서 객체를 생성하고 반환 할 수 있습니다.

할당 자 쌍을 왜 사용 하시겠습니까?



답변

당신이 할 수있는 일 make이 다른 방법으로 할 수 없어 :

  • 채널 만들기
  • 공간이 미리 할당 된 맵 만들기
  • 공간이 미리 할당되거나 len! = cap로 슬라이스를 만듭니다.

정당화하기가 조금 더 어렵습니다 new. 가장 쉬운 것은 비 복합 유형에 대한 포인터를 만드는 것입니다. 아래의 두 기능은 동일합니다. 하나는 조금 더 간결합니다.

func newInt1() *int { return new(int) }

func newInt2() *int {
    var i int
    return &i
}


답변

Go에는 여러 가지 메모리 할당 및 값 초기화 방법이 있습니다.

&T{...}, &someLocalVar, new,make

복합 리터럴을 만들 때 할당이 발생할 수도 있습니다.


new정수와 같은 값을 할당하는 데 사용할 수 있습니다 &int.

new(Point)
&Point{}      // OK
&Point{2, 3}  // Combines allocation and initialization

new(int)
&int          // Illegal

// Works, but it is less convenient to write than new(int)
var i int
&i

의 차이 new와는 make다음의 예를 보면 알 수있다 :

p := new(chan int)   // p has type: *chan int
c := make(chan int)  // c has type: chan int

Go에 newand make가 없지만 내장 기능 이 있다고 가정합니다 NEW. 그런 다음 예제 코드는 다음과 같습니다.

p := NEW(*chan int)  // * is mandatory
c := NEW(chan int)

* 필수가 될 것입니다 그래서 :

new(int)        -->  NEW(*int)
new(Point)      -->  NEW(*Point)
new(chan int)   -->  NEW(*chan int)
make([]int, 10) -->  NEW([]int, 10)

new(Point)  // Illegal
new(int)    // Illegal

예, 단일 내장 기능으로 병합 new및 통합 make할 수 있습니다. 그러나 단일 내장 기능이 내장 된 두 기능을 갖는 것보다 새로운 Go 프로그래머에게 더 많은 혼란을 야기 할 가능성이 있습니다.

위의 모든 사항을 고려하면 더 적절 new하고 make분리 된 상태로 유지됩니다.


답변

make함수는 slice, map 또는 chan 유형의 객체 만 할당하고 초기화합니다. 처럼 new첫 번째 인수는 유형입니다. 그러나 크기에 대한 두 번째 주장이 필요할 수도 있습니다. new와 달리 make의 반환 유형은 포인터의 유형이 아니라 인수의 유형과 동일합니다. 그리고 할당 된 값이 초기화됩니다 (새로운 것과 같이 0으로 설정되지 않음). 그 이유는 slice, map 및 chan이 데이터 구조이기 때문입니다. 초기화해야합니다. 그렇지 않으면 사용할 수 없습니다. 이것이 new ()와 make ()가 달라야하는 이유입니다.

Effective Go의 다음 예는 매우 명확합니다.

p *[]int = new([]int) // *p = nil, which makes p useless
v []int = make([]int, 100) // creates v structure that has pointer to an array, length field, and capacity field. So, v is immediately usable


답변

  • new(T)– 메모리를 할당하고, 집합에 그것은 제로 값 유형에 대한 T ..
    이다 ..that 0대해 INT , ""위한 문자열nil참조 타입 (위한 슬라이스 , 지도 , )

    참조 유형은 일부 단지 포인터 참고 것을 기본 데이터 구조 , 생성되지 않습니다 에 의해 new(T)
    의 경우 : 예 슬라이스 , 기본 배열이 생성되지 않습니다 따라서, new([]int)
    아무것도 포인터를 반환

  • make(T)-참조 된 데이터 유형 ( slice , map , chan )에 메모리를 할당 하고 기본 데이터 구조를 초기화 합니다.

    예 : slice의 경우 지정된 길이와 용량으로 기본 배열 이 생성됩니다.
    C와 달리 배열은 Go!의 기본 유형입니다.


그 말은 :

  • make(T) 복합 리터럴 구문처럼 동작
  • new(T)처럼 행동한다 var(변수가 초기화되지 않은 경우)

    func main() {
        fmt.Println("-- MAKE --")
        a := make([]int, 0)
        aPtr := &a
        fmt.Println("pointer == nil :", *aPtr == nil)
        fmt.Printf("pointer value: %p\n\n", *aPtr)
    
        fmt.Println("-- COMPOSITE LITERAL --")
        b := []int{}
        bPtr := &b
        fmt.Println("pointer == nil :", *bPtr == nil)
        fmt.Printf("pointer value: %p\n\n", *bPtr)
    
        fmt.Println("-- NEW --")
        cPtr := new([]int)
        fmt.Println("pointer == nil :", *cPtr == nil)
        fmt.Printf("pointer value: %p\n\n", *cPtr)
    
        fmt.Println("-- VAR (not initialized) --")
        var d []int
        dPtr := &d
        fmt.Println("pointer == nil :", *dPtr == nil)
        fmt.Printf("pointer value: %p\n", *dPtr)
    }

    프로그램을 실행

    -- MAKE --
    pointer == nil : false
    pointer value: 0x118eff0  # address to underlying array
    
    -- COMPOSITE LITERAL --
    pointer == nil : false
    pointer value: 0x118eff0  # address to underlying array
    
    -- NEW --
    pointer == nil : true
    pointer value: 0x0
    
    -- VAR (not initialized) --
    pointer == nil : true
    pointer value: 0x0

    추가 읽기 :
    https://golang.org/doc/effective_go.html#allocation_new
    https://golang.org/doc/effective_go.html#allocation_make


  • 답변

    당신은 필요한 make()채널과지도를 만들기 위해 (그리고 조각을, 그러나 그 너무 배열을 만들 수 있습니다). 대체 할 방법이 없으므로 make()사전에서 제거 할 수 없습니다 .

    에 관해서는 new(), 나는 어떤 이유를 모르는 즉석 당신이 왜 필요 를 당신은 구조체 구문을 사용할 수 있습니다 때. 그래도 고유 한 의미 론적 의미를 갖습니다. “모든 필드가 0으로 초기화 된 구조체를 생성하여 반환합니다”는 유용합니다.


    답변

    외에도 모든에서이 설명 효과적인 이동 , 주요 차이점을 사이 new(T)&T{} 후자는 명시 적으로 힙 할당을 수행하는 것입니다. 그러나 이는 구현에 따라 다르므로 변경 될 수 있습니다.

    비교 make하려면 new두 개의 완전히 다른 기능을 수행 할 때 약간의 의미가 있습니다. 그러나 이것은 링크 된 기사에서 자세히 설명됩니다.


    답변

    new (T) : 유형 T에 대한 포인터를 * T 유형의 값으로 리턴 하고 메모리를 할당하고 0으로 만듭니다. new (T)는 & T {}와 같습니다 .

    make (T) : T 타입초기화 된 값을 반환하고 , 메모리를 할당하고 초기화합니다. 슬라이스, 맵 및 채널에 사용됩니다.