[go] Go에서 두 조각을 연결

슬라이스 [1, 2]와 슬라이스를 결합하려고합니다 [3, 4]. Go에서 어떻게 할 수 있습니까?

나는 시도했다 :

append([]int{1,2}, []int{3,4})

그러나 얻었다 :

cannot use []int literal (type []int) as type int in append

그러나 문서에는 이것이 가능하다는 것을 나타내는 것 같습니다.

slice = append(slice, anotherSlice...)



답변

두 번째 조각 다음에 점을 추가하십시오.

//---------------------------vvv
append([]int{1,2}, []int{3,4}...)

이것은 다른 variadic 함수와 같습니다.

func foo(is ...int) {
    for i := 0; i < len(is); i++ {
        fmt.Println(is[i])
    }
}

func main() {
    foo([]int{9,8,7,6,5}...)
}


답변

슬라이스에 추가 및 복사

variadic 함수 append
유형 에 0 개 이상의 값 x을 추가합니다 . s이 유형 S은 슬라이스 유형이어야하며 결과 슬라이스도 유형의 형식으로 반환합니다 S. 값은 x타입의 파라미터에 전달 의 요소 타입 과 통과 규칙이 적용되는 각 파라미터. 특별한 경우에 덧붙여 append는 타입 에 두번째 인자가
뒤에 오는 타입에 할당 할 수있는 첫번째 인자를 받아들 입니다. 이 형식은 문자열의 바이트를 추가합니다....TTS[]bytestring...

append(s S, x ...T) S  // T is the element type of S

s0 := []int{0, 0}
s1 := append(s0, 2)        // append a single element     s1 == []int{0, 0, 2}
s2 := append(s1, 3, 5, 7)  // append multiple elements    s2 == []int{0, 0, 2, 3, 5, 7}
s3 := append(s2, s0...)    // append a slice              s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}

… 매개 변수에 인수 전달

f최종 매개 변수 유형이 가변적인 경우 ...T함수 내에서 인수는 유형의 매개 변수와 같습니다 []T. 을 호출 할 때마다 ffinal 매개 변수에 전달 된 인수는 []T연속 요소가 실제 인수 인 새로운 유형 의 조각으로 , 모두 유형에 지정할 수 있어야합니다 T. 따라서 슬라이스 길이는 최종 매개 변수에 바인딩 된 인수의 수이며 각 호출 사이트마다 다를 수 있습니다.

귀하의 질문에 대한 대답은 예입니다 s3 := append(s2, s0...)에서 이동 프로그래밍 언어 사양 . 예를 들어

s := append([]int{1, 2}, []int{3, 4}...)


답변

다른 답변에 반대하는 것은 없지만 문서 의 간단한 설명 이 예제의 예보다 이해하기 쉽다 것을 알았 습니다.

func 추가

func append(slice []Type, elems ...Type) []Type내장 기능 추가 기능은 슬라이스 끝에 요소를 추가합니다. 용량이 충분하면 대상이 새 요소를 수용하도록 슬라이스됩니다. 그렇지 않은 경우 새로운 기본 배열이 할당됩니다. 추가는 업데이트 된 슬라이스를 반환합니다. 따라서 추가 결과를 종종 슬라이스 자체를 보유하는 변수에 저장해야합니다.

slice = append(slice, elem1, elem2)
slice = append(slice, anotherSlice...)

특별한 경우, 다음과 같이 바이트 슬라이스에 문자열을 추가하는 것이 합법적입니다.

slice = append([]byte("hello "), "world"...)

답변

나는 (을 reslicing 대상을 reslicing에 의해 지적하고 대상 슬라이스 (당신이 추가 슬라이스가) 충분한 용량이있는 경우, 추가] “이 자리에서”일어날 것을 아는 것이 중요하다고 생각 증가 될하기 위해 길이를 추가 가능한 요소를 수용 할 수 있음).

즉, 결과 슬라이스의 길이를 초과하는 추가 요소가있는 더 큰 배열이나 슬라이스를 슬라이스하여 대상을 만든 경우 덮어 쓸 수 있습니다.

시연하려면이 예제를 참조하십시오.

a := [10]int{1, 2}
fmt.Printf("a: %v\n", a)

x, y := a[:2], []int{3, 4}
fmt.Printf("x: %v, y: %v\n", x, y)
fmt.Printf("cap(x): %v\n", cap(x))

x = append(x, y...)
fmt.Printf("x: %v\n", x)

fmt.Printf("a: %v\n", a)

출력 ( Go Playground 에서 시도 ) :

a: [1 2 0 0 0 0 0 0 0 0]
x: [1 2], y: [3 4]
cap(x): 10
x: [1 2 3 4]
a: [1 2 3 4 0 0 0 0 0 0]

alength를 가진 “backing”배열 을 만들었습니다 10. 그런 다음 xa배열을 슬라이스 하여 대상 슬라이스를 만들고 y슬라이스는 복합 리터럴을 사용하여 []int{3, 4}만듭니다. 우리가 추가 할 때 지금 yx, 결과는 예상입니다 [1 2 3 4],하지만 놀라게 할 수있다하면 보조 배열이 있다는 것입니다 a용량 때문에 또한, 변경 xIS 10충분 추가하는 y그것, 그래서 x같은 사용되는 resliced되는 a보조 배열을하고, 거기에 append()요소를 복사합니다 y.

이것을 피하려면 다음과 같은 형식 의 전체 슬라이스 식 을 사용할 수 있습니다

a[low : high : max]

슬라이스를 구성하고 결과 슬라이스를로 설정하여 용량을 제어합니다 max - low.

수정 된 예를 참조하십시오 (단지 차이점은 x다음과 같습니다. x = a[:2:2]:

a := [10]int{1, 2}
fmt.Printf("a: %v\n", a)

x, y := a[:2:2], []int{3, 4}
fmt.Printf("x: %v, y: %v\n", x, y)
fmt.Printf("cap(x): %v\n", cap(x))

x = append(x, y...)
fmt.Printf("x: %v\n", x)

fmt.Printf("a: %v\n", a)

출력 ( Go Playground 에서 시도 )

a: [1 2 0 0 0 0 0 0 0 0]
x: [1 2], y: [3 4]
cap(x): 2
x: [1 2 3 4]
a: [1 2 0 0 0 0 0 0 0 0]

보시다시피, 같은 x결과를 얻지 만 a용량 x이 “전용” 이기 때문에 배킹 배열 이 변경되지 않았습니다 2(전체 슬라이스 표현식 덕분에 a[:2:2]). 따라서 추가를 수행하기 위해 x와 의 요소를 모두 저장할 수있는 새로운 배킹 배열이 할당 y됩니다 a.


답변

@icza 답변을 강조하고 중요한 개념이므로 조금 단순화하고 싶습니다. 나는 독자가 슬라이스에 익숙하다고 가정한다 .

c := append(a, b...)

이것은 질문에 대한 올바른 답변입니다.
그러나 나중에 다른 컨텍스트에서 코드에서 슬라이스 ‘a’와 ‘c’를 사용해야하는 경우 슬라이스를 연결하는 안전한 방법이 아닙니다.

설명하기 위해 슬라이스가 아닌 기본 배열의 관점에서 표현식을 읽으십시오.

” ‘a’배열을 가져 와서 ‘b’배열의 요소를 추가하십시오. ‘a’배열에 ‘b’의 모든 요소를 ​​포함 할 수있는 충분한 용량이있는 경우 ‘c’의 기본 배열은 새로운 배열이 아닙니다. 기본적으로 슬라이스 ‘a’는 기본 배열 ‘a’의 len (a) 요소를 표시하고 슬라이스 ‘c’는 배열 ‘a’의 len (c)를 표시합니다. “

append ()가 반드시 새로운 배열을 만들 필요는 없습니다! 예기치 않은 결과가 발생할 수 있습니다. Go Playground example을 참조하십시오 .

슬라이스에 새 배열이 할당되도록하려면 항상 make () 함수를 사용하십시오. 예를 들어 여기에는 작업에 대한 추악하지만 효율적인 옵션이 거의 없습니다.

la := len(a)
c := make([]int, la, la + len(b))
_ = copy(c, a)
c = append(c, b...)

la := len(a)
c := make([]int, la + len(b))
_ = copy(c, a)
_ = copy(c[la:], b)


답변

append () 함수 및 확산 연산자

append표준 golang 라이브러리의 메소드를 사용하여 두 개의 슬라이스를 연결할 수 있습니다 . variadic기능 작동 과 유사 합니다. 그래서 우리는 사용해야합니다...

package main

import (
    "fmt"
)

func main() {
    x := []int{1, 2, 3}
    y := []int{4, 5, 6}
    z := append([]int{}, append(x, y...)...)
    fmt.Println(z)
}

위 코드의 출력은 다음과 같습니다. [1 2 3 4 5 6]


답변

append([]int{1,2}, []int{3,4}...)작동합니다. ...매개 변수에 인수 전달

유형 f이 final 인 variadic 인 경우 p유형 ...Tf에서 type과 p같습니다 []T.

f에 대한 실제 인수없이 호출 된 경우 p전달 된 값 pnil입니다.

그렇지 않으면, 전달 된 값은 []T연속적인 요소가 실제 인수 인 새로운 기본 배열이있는 새로운 유형의 조각이며 모두 할당 할 수 있어야합니다 T. 따라서 슬라이스의 길이와 용량은 p각 호출 사이트에 바인딩 된 인수 수이며 각 호출 사이트마다 다를 수 있습니다.

주어진 함수와 호출

func Greeting(prefix string, who ...string)
Greeting("nobody")
Greeting("hello:", "Joe", "Anna", "Eileen")