>  기사  >  백엔드 개발  >  루프의 슬라이스에 추가하는 것이 Go의 다른 슬라이스에 영향을 미치는 이유는 무엇입니까?

루프의 슬라이스에 추가하는 것이 Go의 다른 슬라이스에 영향을 미치는 이유는 무엇입니까?

Barbara Streisand
Barbara Streisand원래의
2024-11-06 04:05:02962검색

Why Does Appending to a Slice in a Loop Affect Other Slices in Go?

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.