Slice Append의 예기치 않은 동작: 수정 문제 없이 여러 슬라이스를 생성하는 방법
Go 코드에서 슬라이스를 조작할 때 당황스러운 문제가 발생할 수 있습니다. 문제: 루프 내의 슬라이스에 요소를 추가한 다음 루프 결과를 사용하여 새 슬라이스를 생성하면 마지막 추가가 이전 추가의 슬라이스를 재정의할 수 있습니다. 이 동작은 슬라이스가 동일한 기본 배열 값을 참조하기 때문에 발생합니다.
예:
<code class="go">func create(iterations int) []int { a := make([]int, 0) for i := 0; i < iterations; i++ { a = append(a, i) } return a } func sliceFromLoop() { i := create(11) j := append(i, 100) g := append(i, 101) h := append(i, 102) fmt.Printf("i: %v\nj: %v\ng: %v\nh:%v\n", i, j, g, h) }</code>
이 예에서 SliceFromLoop 함수는 슬라이스 i를 생성하고 서로 다른 슬라이스를 추가합니다. 결과적으로 j, g, h 조각이 생성됩니다. 그러나 세 개의 슬라이스는 모두 동일한 기본 배열을 가리키므로 마지막 추가로 배열이 수정되면 모든 슬라이스에 영향을 미칩니다.
해결책: 독립적 수정을 위한 슬라이스 복사
기존 슬라이스를 기반으로 여러 슬라이스를 생성하고 수정 문제를 피하는 관용적인 방법은 항목을 추가하기 전에 슬라이스를 복사하는 것입니다. 이렇게 하면 각각의 새 슬라이스에 고유한 기본 배열이 있습니다.
<code class="go">func makeFromSlice(sl []int) []int { result := make([]int, len(sl)) copy(result, sl) return result }</code>
사용 예:
<code class="go">func main() { i := make([]int, 0) for ii := 0; ii < 11; ii++ { i = append(i, ii) } j := append(makeFromSlice(i), 100) // works fine }</code>
이 수정된 예에서는 나는 그것에 100을 추가하기 전에 슬라이스합니다. 이렇게 하면 j가 별도의 기본 배열을 참조하고 향후 i 수정으로 인해 영향을 받지 않습니다.
슬라이스 리터럴 동작 설명
이 문제가 발생하는 이유 슬라이스 리터럴(예: i := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10})이 발생하지 않는 이유는 추가 작업이 다음과 같은 경우 새 배열이 할당된다는 것입니다. 백업 어레이의 용량을 초과했습니다. 이 동작은 슬라이스 리터럴과 관련이 없으며 슬라이스에 추가하는 기본 속성입니다.
위 내용은 루프의 슬라이스에 추가하는 것이 Go의 다른 슬라이스에 영향을 미치는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!