programing

왜 json은?포인터가 아닌 참조를 사용하여 마샬을 해제하시겠습니까?

telecom 2023. 3. 11. 08:35
반응형

왜 json은?포인터가 아닌 참조를 사용하여 마샬을 해제하시겠습니까?

예시는 json의 것입니다.Unmarshal 문서(사용하기 쉽도록 약간 수정)Animal대신[]Animal)는 동작합니다.에러는 없습니다.

작업 예제의 놀이터 링크

// ...
var animals Animal
err := json.Unmarshal(jsonBlob, &animals)
// ...

다만, 이 약간 변경된 예에서는, 다음과 같이 되어 있지 않습니다.

작동하지 않는 예제의 놀이터 링크

// ...
var animals *Animal
err := json.Unmarshal(jsonBlob, animals)
// ...

실제로는 도움이 되지 않는 불명확한 에러가 표시됩니다(오류 IMO라기보다는 함수 호출에 가깝습니다).

언마샬(nil *main).동물)

그 이유는 다음과 같습니다.animals는 초기화되지 않은 포인터입니다.하지만 의사들이 말하길, (내 것을 강조한다)

포인터가 가리키는 값으로 JSON의 마샬을 해제합니다.포인터가 제로일 경우 포인터가 가리키는 새 값이 할당됩니다.

그렇다면 왜 두 번째 예에서는 마샬링이 실패하고 불분명한 오류가 나타나는 것일까요?

(또, 「언마샬링」인가, 「언마샬링」인가(1 L)인가).이 문서들은 둘 다 사용합니다.)

InvalidUnmarshalError가 발생했습니다(decode.go의 109행과 110행 참조).

// InvalidUnmarshalError는 Unmarshal에 전달된 잘못된 인수를 나타냅니다.
// (Unmarshal에 대한 인수는 nil이 아닌 포인터여야 합니다.)

위 인용문과 아래 소스의 코멘트가 서로 모순되는 것 같기 때문에, 이 문서들은 어느 정도 설명이 필요할 것 같습니다.

포인터가 제로일 경우 포인터가 가리키는 새 값이 할당됩니다.

포인터가 0이니까요

초기화하면 동작합니다.http://play.golang.org/p/zprmV0O1fG

var animals *Animal = &Animal{}

, 어느쪽이든 철자가 가능합니다(단, 1개의 문서 내에서 일관성을 유지하는 것이 좋습니다).

문제는 0 포인터를 Unmarshal()에 전달할 수 있지만 0 포인터 값을 전달할 수 없다는 것입니다.

0 포인터는 다음과 같습니다.

var v interface{}
json.Unmarshal(text, &v)

가치v는 제로입니다만, 에의 포인터입니다.v는 제로 이외의 포인터 주소입니다.제로 이외의 포인터로, 제로 인터페이스{}(그 자체가 포인터 타입)를 가리키고 있습니다.이 경우 Unmarshal은 오류를 반환하지 않습니다.

제로 포인터는 다음과 같습니다.

var v *interface{}
json.Unmarshal(text, v)

이 경우 v의 유형은 다음과 같습니다.pointer to an interface{}단, 골랑에서의 var 선언과 마찬가지로 초기값v는 타입의 제로값입니다.그렇게v는 제로값 포인터입니다.즉, 메모리내의 유효한 장소를 가리키고 있지 않습니다.

https://stackoverflow.com/a/20478917/387176, json에서 설명한 바와 같이Unmarshal()에는 유효한 포인터가 필요하기 때문에 제로값 구조체 또는 포인터 등 무엇인가를 변경할 수 있습니다.

이전에도 비슷한 증상이 있었지만, 다른 경우였습니다.바둑의 인터페이스 개념과 관련이 있습니다.함수가 인터페이스를 인수 또는 반환 값으로 선언한 경우 발신자는 참조를 전달 또는 반환해야 합니다.

ㅇㅇㅇㅇㅇㅇ는json.Unmarshal를 두 번째

언급URL : https://stackoverflow.com/questions/20478577/why-does-json-unmarshal-work-with-reference-but-not-pointer

반응형