>백엔드 개발 >Golang >원래 Go 슬라이스를 반영.추가하지 않는 이유는 무엇이며 어떻게 해결할 수 있습니까?

원래 Go 슬라이스를 반영.추가하지 않는 이유는 무엇이며 어떻게 해결할 수 있습니까?

DDD
DDD원래의
2024-12-04 10:51:101002검색

Why Doesn't Reflect.Append Modify the Original Go Slice, and How Can I Fix It?

리플렉션을 사용하여 Go Lang 슬라이스에 추가: 메커니즘 이해

리플렉션을 사용하여 슬라이스에 새 요소를 추가하려고 하면 다음과 같습니다. 그에 따라 원본 슬라이스가 업데이트될 것으로 예상됩니다. 그러나 다음 코드에서 알 수 있듯이 이것이 발생하지 않는 것을 볼 수 있습니다.

import (
    "fmt"
    "reflect"
)

func appendToSlice(arrPtr interface{}) {
    valuePtr := reflect.ValueOf(arrPtr)
    value := valuePtr.Elem()
    value = reflect.Append(value, reflect.ValueOf(55))

    fmt.Println(value.Len()) // prints 1
}

func main() {
    arr := []int{}
    appendToSlice(&arr)
    fmt.Println(len(arr)) // prints 0
}

이유 이해

이 동작을 이해하는 열쇠는 다음과 같습니다. Reflect.Append가 어떻게 작동하는지 인식합니다. 표준 라이브러리의 추가 기능과 유사하게, Reflect.Append는 원본을 수정하는 대신 새 슬라이스 값을 생성합니다. 위의 코드 조각에서 값은 새로 생성된 슬라이스에 할당되어 함수 내의 원래 값을 대체하지만 함수 외부의 원래 인수에는 영향을 주지 않습니다.

접근 방식 수정

리플렉션을 사용하여 원본 슬라이스를 수정하려면 Value.Set 메서드를 사용해야 합니다. 이 방법을 사용하면 원래 값을 업데이트할 수 있습니다. AppendToSlice 함수의 수정된 버전은 다음과 같습니다.

func appendToSlice(arrPtr interface{}) {
    valuePtr := reflect.ValueOf(arrPtr)
    value := valuePtr.Elem()

    value.Set(reflect.Append(value, reflect.ValueOf(55)))

    fmt.Println(value.Len())
}

이렇게 하면 원본 슬라이스가 예상대로 수정되고 다음 출력이 얻어집니다.

1
1

결론

플렉션을 사용하여 슬라이스를 수정할 때 리플렉션을 고려하는 것이 중요합니다. 추가하면 새 슬라이스가 생성됩니다. 원본을 수정하는 것보다 Value.Set 메서드를 활용하면 반사를 통해 원본 슬라이스를 효과적으로 수정하여 예상한 결과를 얻을 수 있습니다.

위 내용은 원래 Go 슬라이스를 반영.추가하지 않는 이유는 무엇이며 어떻게 해결할 수 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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