슬라이스를 선언하거나 슬라이스를 만드시겠습니까?


99

이동에서의 차이 무엇 var s []ints := make([]int, 0)?

두 가지 모두 작동하지만 어느 것이 더 낫습니까?


첫 번째는 nil슬라이스를 생성 하고 두 번째는 empty슬라이스를 생성합니다 ( "Go in action book"에서 사용하는 용어 ). 여기에도 동일한 답변을 게시하지 않으려면 stackoverflow.com/a/45997533/1561148
tgogos

답변:


95

fabriziom답변 외에도 " Go Slices : usage and internals " 에서 더 많은 예제를 볼 수 있습니다 []int.

슬라이스 ( nil) 의 0 값은 길이0 인 슬라이스 처럼 작동 하므로 슬라이스 변수를 선언 한 다음 루프에서 추가 할 수 있습니다.

// Filter returns a new slice holding only
// the elements of s that satisfy f()
func Filter(s []int, fn func(int) bool) []int {
    var p []int // == nil
    for _, v := range s {
        if fn(v) {
            p = append(p, v)
        }
    }
    return p
}

즉, 슬라이스에 추가하기 위해 먼저 메모리를 할당 할 필요가 없습니다. nil슬라이스 p int[]는 추가 할 슬라이스로 충분합니다.


왜 할당을 할 것이라고 생각합니까? Cap은 0이므로 make와 상관없이 아무것도 할당되지 않습니다.
Arman Ordookhani

1
@ArmanOrdookhani 동의합니다. var p []int사용 make하는 것보다 선언이 더 쉽다는 것을 알게 됩니다. 가독성 측면에서 make여기 에서는 사용하지 않는 것이 좋습니다.
VonC

1
나는 어디에서나 리터럴을 사용하는 것에 더 가깝습니다 (예 :) p := []int{}. 우리는 일반적으로 :=대부분의 변수를 선언 하기 위해 구문을 사용하기 때문에 슬라이스에 대한 예외를 갖는 대신 모든 곳에 사용하는 것이 더 자연 스럽습니다. 할당을 생각하는 것 외에는 일반적으로 사람들을 조기 최적화로 밀어 붙입니다.
Arman Ordookhani

113

간단한 선언

var s []int

메모리 할당하지 않습니다 s에 포인트를 nil하면서,

s := make([]int, 0)

메모리를 할당하고 s요소가 0 인 슬라이스에 메모리를 가리 킵니다.

일반적으로 첫 번째는 사용 사례의 정확한 크기를 모르는 경우 더 관용적입니다.


지도에도 똑같이 말할 수 있습니까? var m map [string] int 대 m : = make (map [string] int)? 감사.
조슈아

11
아뇨, make지도 를 작성 해야합니다 . 비어있는 경우에도 map일부 부기를위한 공간이 필요 하기 때문 입니다.
twotwotwo 2015-08-07

11
요소가 0 인 슬라이스 ( 'nil'대신)를 반환해야하는 경우 make가 올바른 사용법입니다.
Jess

6
API를 빌드하고 응답으로 배열을 반환하는 경우 선언적 형식을 사용하면 nil슬라이스에 빈 배열이 아닌 요소가없는 경우 반환 됩니다. 그러나 make를 사용하여 슬라이스를 만들면 대신 빈 배열이 반환되며 이는 일반적으로 원하는 효과입니다.
robinmitra

6
이 답변에 대한 의견에서 언급했듯이 stackoverflow.com/a/29164565/1311538 , json 마샬링과 같은 작업을 시도 할 때 차이점이 있습니다. 전무 슬라이스 (마샬링 var s []int) 생산합니다 null빈 조각 (마샬링 동안 것은 s := make([]int, 0)) 예상 생산합니다[]
asgaines

8

방금 차이를 찾았습니다. 사용하는 경우

var list []MyObjects

출력을 JSON으로 인코딩하면 null.

list := make([]MyObjects, 0)

결과 []예상대로.


yah, 후자는 null 대신 [] 배열로 응답 할 때 매우 유용합니다
Nhan Tran

4

좀 더 완전하게 (에서 하나 이상의 인수 make) 예제 :

slice := make([]int, 2, 5)
fmt.Printf("length:  %d - capacity %d - content:  %d", len(slice), cap(slice), slice)

밖:

length:  2 - capacity 5 - content:  [0 0]

또는 동적 유형 slice:

slice := make([]interface{}, 2, 5)
fmt.Printf("length:  %d - capacity %d - content:  %d", len(slice), cap(slice), slice)

밖:

length:  2 - capacity 5 - content:  [<nil> <nil>]

2
좋은 예. +1
VonC
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.