>source

여기에 필요한 도식적인 예가 있습니다.

func decode(data []byte, target interface{}) (interface{}, error) {
    decoded := target.(reflect.TypeOf(target)) //pseudocode
    err := json.Unmarshal(data, &
decoded)
    ...

SO에 대한 몇 가지 유사한 질문을 찾았지만 모든 솔루션은대상.(유형). 이것은 내가 찾는 최고의 솔루션이 아닙니다.

또한 리플렉션을 사용하여 솔루션을 찾았습니다.

decoded := reflect.ValueOf(target).Convert(reflect.TypeOf(target))
//fmt.Printf("%T", decoded)== reflect.Value

하지만 구조체를 가져오는 방법을 이해할 수 없었습니다.반영하다.가치그것을 전달하기 위해json.정렬 해제기능.

이것이 어떻게풀다기능이 사용됩니까?

구조가 다른 여러 요청이 있습니다. 요청을 디코딩하는 데 사용해야 하는 구조체를 결정할 수 있습니다. 다음과 같은 요청 유형과 구조 간의 매핑이 있습니다.지도[RequestMethod]인터페이스{}.

도식 버전은 다음과 같습니다.

func hydrate(data []byte) (interface{}, error) {
    var base baseResponse
    if err := json.Unmarshal(data, &
base); err != nil {
        return nil, err
    }
    target, ok := methodsMap[Method(base.Method)]
    if !ok {
        return nil, errors.New("Trying to hydrate data with unknown method: " + base.Method)
    }
    decoded, err := decode(data, target) //Expected target type.

추가됨:

우리가 우리의표적에게json.정렬 해제유형을 캐스팅하지 않고 우리는 얻을 것입니다지도. 예시:

func decode(data []byte, target interface{}) (interface{}, error) {
    err := json.Unmarshal(data, &
target)
    //fmt.Printf("%T", target)== map[string]interface{} not struct.

해결책

덕분에 @icza우리는 해결책을 찾았습니다:

func hydrate(data []byte) (interface{}, error) {
    var base baseResponse
    if err := json.Unmarshal(data, &
base); err != nil {
        return nil, err
    }
    target, ok := methodsMap[Method(base.Method)]
    if !ok {
        return nil, errors.New("Trying to hydrate data with unknown method: " + base.Method)
    }
    //Clone request draft struct.
    decoded := reflect.New(reflect.ValueOf(target).Type()).Interface()
    err := decode(data, decoded)
    ...

관련 링크:

이것은 매우 불필요해 보입니다. 단순히 대상을 json.Unmarshal에 전달하면 잘 작동합니다.

Tim Cooper2022-01-13 08:39:13

이 decode() 함수를 호출하는 방법을 보여주세요. 잘못된 값을 전달했을 가능성이 큽니다.

icza2022-01-13 08:39:13

인터페이스에 값 전달의 중복 가능성{}; 및 Golang 인터페이스{} 유형 오해.

icza2022-01-13 08:39:13

@AlexBor 내 다른 답변을 읽으면 아무 것도 변환할 필요가 없습니다. 당신이 잘못한 곳은 당신의 디code() 함수를 호출하는 것입니다: 당신은 그것에 대한 구조체에 대한 포인터를 전달해야 합니다. Decode() 내부에서 인터페이스 값을{} json.Unmarshal()에 전달하면 됩니다.

icza2022-01-13 08:39:13

@AlexBor 최종 유형 어설션은 생략하십시오. 나중에 작업했기 때문에 거기에서 사용했습니다. 그냥 Reflect.New(...).Interface()를 사용하세요.

icza2022-01-13 08:39:13
  • 이전 sql : 바나나는 좋아하지만 사과는 좋아하지 않는 고객 -쿼리 개선
  • 다음 PHP를 사용하여 Curl에서 .PEM 및 .KEY를 문자열로 전달