programing

JSON 및 내 보내지 않은 필드 처리

nasanasas 2020. 12. 3. 08:00
반응형

JSON 및 내 보내지 않은 필드 처리


인코딩 / json에 내 보내지 않은 필드가 포함되지 않는 기술적 이유가 있습니까? 그렇지 않은 경우 임의의 결정으로 내 보내지 않은 경우에도 포함 할 추가 백도어 옵션 (예 : '+')이있을 수 있습니까?

이 기능을 얻기 위해 클라이언트 코드를 내보내도록 요구하는 것은 특히 소문자가 캡슐화를 제공하거나 구조를 마샬링하는 결정이 구조 설계보다 훨씬 늦게 오는 경우 불행하게 느껴집니다.

사람들은 이것을 어떻게 처리하고 있습니까? 모두 내보내시겠습니까?

또한 필드 이름을 내 보내지 않으면 제안 된 관용구를 따르기가 어렵습니다. 구조체 X에 필드 Y가 있으면 접근 자 메서드 Y ()를 가질 수 없다고 생각합니다. Y에 대한 인터페이스 액세스를 제공하려면 getter의 새 이름을 만들어야하며 http://golang.org/doc/effective_go.html#Getters 에 따라 비정상적인 것을 얻을 수 있습니다.


기술적 이유가 있습니다. json 라이브러리에는 반출되지 않는 한 reflect를 사용하여 필드를 볼 수있는 권한이 없습니다. 패키지는 자체 패키지 내에서 내 보내지 않은 유형의 필드 만 볼 수 있습니다.

문제를 해결하기 위해 할 수있는 일은 내 보낸 필드로 내 보내지 않은 유형을 만드는 것입니다. Json은 문제없이 전달되면 내 보내지 않은 유형으로 비 정렬 화되지만 API 문서에는 표시되지 않습니다. 그런 다음 내 보내지 않은 유형을 포함하는 내 보낸 유형을 만들 수 있습니다. 이 내 보낸 유형에는 json.Marshalerjson.Unmarshaler인터페이스 를 구현하기위한 메소드가 필요합니다 .

참고 : 모든 코드는 테스트되지 않았으며 컴파일되지 않을 수도 있습니다.

type jsonData struct {
    Field1 string
    Field2 string
}

type JsonData struct {
    jsonData
}

// Implement json.Unmarshaller
func (d *JsonData) UnmarshalJSON(b []byte) error {
    return json.Unmarshal(b, &d.jsonData)
}

// Getter
func (d *JsonData) Field1() string {
    return d.jsonData.Field1
}

Stephen의 대답이 완성되었습니다. 제쳐두고, 정말로 원하는 것이 json의 소문자 키라면 다음과 같이 수동으로 키 이름을 지정할 수 있습니다.

type Whatever struct {
    SomeField int `json:"some_field"`
}

그런 식으로 Whatever를 마샬링하면 SomeField 필드에 대한 키 "some_field"가 생성됩니다 (json에 "SomeField"가있는 대신).

내 보내지 않은 필드를 유지하는 데 어려움을 겪고 있다면 서명을 사용하여 메서드를 정의하여 json.Marshaler 인터페이스를 구현할 수도 있습니다 MarshalJSON() ([]byte, error). 이를 수행하는 한 가지 방법은 다음과 같이 내 보내지 않은 필드의 내 보낸 버전이있는 구조체 리터럴을 사용하는 것입니다.

type Whatever struct {
    someField int
}

func (w Whatever) MarshalJSON() ([]byte, error) {
    return json.Marshal(struct{
        SomeField int `json:"some_field"`
    }{
        SomeField: w.someField,
    })
}

약간 번거로울 수 있으므로 map[string]interface{}원하는 경우 a를 사용할 수도 있습니다 .

func (w Whatever) MarshalJSON() ([]byte, error) {
    return json.Marshal(map[string]interface{}{
        "some_field": w.SomeField,
    })
}

그러나 마샬링 interface{}에는 몇 가지주의 사항 uint64이 있으며 플로트에 마샬링 하는 것과 같은 작업을 수행 하여 정밀도가 떨어질 수 있습니다. (모든 코드는 테스트되지 않음)

참고 URL : https://stackoverflow.com/questions/11126793/json-and-dealing-with-unexported-fields

반응형