인터페이스{} 유형에 대한 오해: 복잡성 공개
Go에서 인터페이스{} 유형은 유연성과 복잡성을 모두 제공합니다. 그러나 그 성격을 오해하면 수수께끼 같은 예에서 알 수 있듯이 예상치 못한 결과를 초래할 수 있습니다.
포인터가 아닌 유형을 인터페이스 매개변수로 함수에 전달하고 json.Unmarshal을 사용하려고 하면, 결과는 놀라울 수 있습니다. 아래 예는 이 동작을 보여줍니다.
package main import ( "encoding/json" "fmt" ) 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) } type Test struct { Foo string } func main() { test(Test{}) }
출력:
main.Test *interface {} map[string]interface {}
Unveiling the Mystery
혼란은 인터페이스의 특성에서 비롯됩니다. {}. 이는 단순히 유형이 없는 컨테이너가 아니라 (값, 유형) 쌍에 대한 래퍼입니다. 인터페이스는 구체적인 값과 해당 유형에 대한 참조를 저장합니다.
json.Unmarshal은 인터페이스{} 값을 입력으로 사용하므로 i를 직접 전달할 수 있습니다. (&i와 마찬가지로) 해당 주소를 가져오려는 시도는 불필요합니다.
포인터 및 인터페이스
그러나 i에 포인터가 아닌 값이 포함되어 있으면 json.Unmarshal은 다음과 같은 문제에 직면합니다. 도전. 패키지는 비포인터로 역마샬링할 수 없으므로 인터페이스{} 유형의 새 값을 생성합니다. 이를 통해 기본적으로 map[string]interface{}로 설정된 유형을 선택할 수 있습니다.
올바른 시나리오
포인터 시나리오의 경우 &i를 인수로 전달 json.Unmarshal이 포인터를 역참조하여 *Test 값이 포함된 인터페이스 값을 찾기 때문에 작동합니다. 포인터는 올바른 유형으로 역마샬링이 발생하도록 보장합니다.
결론
이러한 혼란을 피하려면 인터페이스에 대한 포인터를 사용하지 마십시오. 대신, 인터페이스 내에 포인터를 "배치"하고 직접 전달하십시오. 인터페이스와 포인터 간의 상호 작용을 이해함으로써 개발자는 예상치 못한 결과를 방지하고 Go의 유형 시스템을 효과적으로 활용할 수 있습니다.
위 내용은 포인터가 아닌 `interface{}` 매개변수가 포함된 `json.Unmarshal`이 Go에서 예상치 못한 결과를 생성하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!