>백엔드 개발 >Golang >`interface{}`를 사용할 때 `json.Unmarshal`이 내 구조체를 예기치 않게 변경하는 이유는 무엇입니까?

`interface{}`를 사용할 때 `json.Unmarshal`이 내 구조체를 예기치 않게 변경하는 이유는 무엇입니까?

Barbara Streisand
Barbara Streisand원래의
2024-12-12 19:53:11215검색

Why Does `json.Unmarshal` Unexpectedly Change My Struct When Using `interface{}`?

Go 인터페이스{} 유형에 대한 오해

배경

Go 프로그래밍의 중요한 측면인 인터페이스{} 유형은 값을 사용하지만 종종 오해를 불러일으킬 수 있습니다.

예상치 못한 버그 json.Unmarshal

인터페이스{}를 함수 매개변수로 사용하고 json.Unmarshal에 문제가 발생할 때 일반적인 오해가 발생합니다. 다음 코드 조각은 이 버그를 보여줍니다.

func test(i interface{}) {
    j := []byte(`{ "foo": "bar" }`)
    fmt.Printf("%T\n", i)
    fmt.Printf("%T\n", &i)
    json.Unmarshal(j, &i)
    fmt.Printf("%T\n", i)
}

func main() {
    test(Test{})
}

type Test struct {
    Foo string
}

실행 시 이 코드는 출력에서 ​​볼 수 있듯이 정렬 해제된 후 예기치 않게 구조체 Test{}를 map[string]interface{}로 변환합니다.

main.Test
*interface {}
map[string]interface {}

오해에 대한 이해

오해는 인터페이스{} 유형. 일부 사람들이 가정하는 것처럼 빈 컨테이너가 아니라 값 유형 쌍에 대한 래퍼입니다. 포인터가 아닌 Test{}가 test()에 전달되면 json.Unmarshal 함수는 포인터를 예상하여 대신 새 map[string]interface{} 값을 생성하게 됩니다.

이 문제를 해결하려면 , 인터페이스{} 매개변수에 대한 포인터를 전달해야 합니다.

func test(i interface{}) {
    j := []byte(`{ "foo": "bar" }`)
    fmt.Printf("%T\n", i)
    fmt.Printf("%T\n", &i)
    json.Unmarshal(j, i)
    fmt.Printf("%T\n", i)
    fmt.Println(i)
}

func main() {
    test(&Test{})
}

이 수정을 통해 포인터에 대한 포인터가 함수에 전달되어 json.Unmarshal이 허용됩니다. JSON 데이터를 올바르게 역마샬링하려면

결론

인터페이스는{}예기치 않은 동작을 방지하기 위해 주의 깊게 사용해야 한다는 점을 기억하는 것이 중요합니다. 효과적인 Go 개발을 위해서는 기본 구현과 json.Unmarshal과 같은 기능에 미치는 영향을 이해하는 것이 필수적입니다.

위 내용은 `interface{}`를 사용할 때 `json.Unmarshal`이 내 구조체를 예기치 않게 변경하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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