답변:
두 번째 조각 다음에 점을 추가하십시오.
//---------------------------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}...)
}
foo()
예에서 is
매개 변수는 원래 슬라이스의 사본을 보유합니다. 즉, 동일한 기본 배열, len 및 cap에 대한 경량 참조 사본이 있습니다. 는 IF foo
함수 바꾸는 부재 변화는 원래의 알 수있을 것이다. 여기 데모가 있습니다. 따라서 실제 오버 헤드는 새 슬라이스가없는 경우 foo(1, 2, 3, 4, 5)
새 슬라이스를 만드는 것입니다 . 예 : 보유 할 새 슬라이스를 만듭니다 is
.
variadic 함수
append
는 유형 에 0 개 이상의 값x
을 추가합니다 .s
이 유형S
은 슬라이스 유형이어야하며 결과 슬라이스도 유형의 형식으로 반환합니다S
. 값은x
타입의 파라미터에 전달 의 요소 타입 과 통과 규칙이 적용되는 각 파라미터. 특별한 경우에 덧붙여 append는 타입 에 두번째 인자가 뒤에 오는 타입에 할당 할 수있는 첫번째 인자를 받아들 입니다. 이 형식은 문자열의 바이트를 추가합니다....T
T
S
[]byte
string
...
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
. 을 호출 할 때마다f
final 매개 변수에 전달 된 인수는[]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]
a
length를 가진 "backing"배열 을 만들었습니다 10
. 그런 다음 x
이 a
배열을 슬라이스 하여 대상 슬라이스를 만들고 y
슬라이스는 복합 리터럴을 사용하여 []int{3, 4}
만듭니다. 우리가 추가 할 때 지금 y
에 x
, 결과는 예상입니다 [1 2 3 4]
,하지만 놀라게 할 수있다하면 보조 배열이 있다는 것입니다 a
용량 때문에 또한, 변경 x
IS 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
표준 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
유형 ...T
내 f
에서 type과 p
같습니다 []T
.
f
에 대한 실제 인수없이 호출 된 경우 p
전달 된 값 p
은 nil
입니다.
그렇지 않으면, 전달 된 값은 []T
연속적인 요소가 실제 인수 인 새로운 기본 배열이있는 새로운 유형의 조각이며 모두 할당 할 수 있어야합니다 T
. 따라서 슬라이스의 길이와 용량은 p
각 호출 사이트에 바인딩 된 인수 수이며 각 호출 사이트마다 다를 수 있습니다.
주어진 함수와 호출
func Greeting(prefix string, who ...string)
Greeting("nobody")
Greeting("hello:", "Joe", "Anna", "Eileen")
append()
variadic 함수를...
사용하면 슬라이스에서 variadic 함수에 여러 인수를 전달할 수 있습니다.