2017-09-27 1 views
0

Golang의 인터페이스에서 필드 값을 가져 오려고합니다. 인터페이스는 처음에는 데이터베이스 결과에서 값을 가져 오는 빈 인터페이스입니다. DB 쿼리가 정상적으로 작동합니다.Golang에서 선언 구조가없는 인터페이스에서 인터페이스 필드 값 가져 오기

내가 필요한 유일한 것은 인터페이스의 필드 값을 가져와야한다는 것입니다. t가 인터페이스를 갖는 다음과 같은 값입니다

s := reflect.ValueOf(t) 
    for i := 0; i < s.Len(); i++ { 
     fmt.Println(s.Index(i)) 
    } 

: 다음은 내 코드입니다

map[id:null count:1] 

단순히 1

처럼 "count"의 값을 원하는 내 문제는 그 지수() 메서드는 구조체가 필요하기 때문에 공황 상태를 반환하고 여기에는 구조체가 없습니다. 그렇다면 인터페이스 값을 얻으려면 어떻게해야합니까? Golang의 리플렉션 패키지를 사용하거나 사용하지 않고 필드 값을 얻기 위해 인터페이스를 반복 할 수있는 솔루션이 있습니까?

편집

카운트 값을 얻기 후에 나는 JSON을 구문 분석 할 필요가있다. 위의 코드는 API의 응답으로이 응답을 사용하여 JSON 형식으로 ratingCount를 얻기 위해 사용되는

type ResponseControllerList struct{ 
    Code   int    `json:"code"` 
    ApiStatus  int    `json:"api_status"` 
    Message   string   `json:"message"` 
    Data   interface{}  `json:"data,omitempty"` 
    TotalRecord  interface{}  `json:"total_record,omitempty"` 
} 
response := ResponseControllerList{} 
ratingsCount := reflect.ValueOf(ratingsCountInterface).MapIndex(reflect.ValueOf("count")) 
fmt.Println(ratingsCount) 

response = ResponseControllerList{ 
       200, 
       1, 
       "success", 
       nil, 
       ratingsCount, 
      } 
GetResponseList(c, response) 

func GetResponseList(c *gin.Context, response ResponseControllerList) { 
    c.JSON(200, gin.H{ 
     "response": response, 
    }) 
} 

:

여기 내 코드입니다. 이 코드에서는 GIN 프레임 워크를 사용하여 API에 HTTP 요청을합니다.

이제는 변수 ratingsCount을 인쇄 할 때 터미널에 필요한 정확한 값을 표시하는 것이 문제입니다. JSON에서 계수의 실제 값을 얻을 수있는 방법은 무엇

{ 
    "response": { 
     "code": 200, 
     "api_status": 1, 
     "message": "Success", 
     "total_record": { 
      "flag": 148 
     } 
    } 
} 

: 내가 JSON에 전달하고 때, 같은 변수 나 같은 응답을 준다?

+0

"는 구조체가 필요하기 때문에 지수() 메소드는 공황을 반환"

나는 형의 주장을 사용하여이 예를 들어 작업 기록했다. 색인은 조각과 배열에서 작동합니다. 문제가 무엇인지 자세히 설명해 주시겠습니까? 예 :당신의't' 인터페이스는 JSON처럼 보이고 Go 인터페이스 타입처럼 보이지 않습니까? – Volker

+0

사실 json에 대한 인터페이스를 구문 분석하고있었습니다. 이제 인터페이스를 편집했습니다. Index()는지도를 가져 오기 때문에 당황합니다. 지도가 색인과 함께 작동하도록 정의되지 않았습니다. 권리 ? 난 그냥 인터페이스에서 "카운트"필드 값을 얻고 싶습니다. –

+0

https://golang.org/pkg/reflect/#Value.MapIndex – Volker

답변

1

리플렉션 대신 유형 어설 션을 사용할 수 있습니다. 가능한 한 언제나 반성을 피하는 것이 좋습니다. 당신이 정말로 반사를 사용하려면

m, ok := t.(map[string]interface{}) 
if !ok { 
    return fmt.Errorf("want type map[string]interface{}; got %T", t) 
} 
for k, v := range m { 
    fmt.Println(k, "=>", v) 
} 

, 당신은 같은 것을 할 수 있습니다

s := reflect.ValueOf(t) 
for _, k := range s.MapKeys() { 
    fmt.Println(s.MapIndex(k)) 
} 

업데이트 그것은 당신이 있기 때문에 무엇을 기대 반환하지 않습니다

당신의 최신 업데이트에 댓글을 올리려면 reflect.Value을 반환합니다. 정수 값을 원하면 ratingsCount.Int()을 사용해야합니다.

하지만 이전에 말했듯이 리플렉션을 사용하지 마십시오. assertion 형식의 첫 번째 솔루션을 사용하고 m["count"]으로 계산하십시오. 잘못 https://play.golang.org/p/9gzwtJIfd7

+0

내 질문에 답해 주셔서 감사합니다. 나는 귀하의 솔루션과 그 벌금 가치를 얻을 벌금을 확인했습니다. 하지만 json에서이 카운트 값을 얻기 위해 내 게시물을 편집했습니다. 필요한 경우 솔루션을 확인하고 제공하십시오. –

+0

글쎄 @ R3v4n, 형식 어설 션도'ratingsCount.Int()'도 작동하지 않습니다. 어설 션을 입력하면 빈 맵이 반환됩니다. 또한'ratingsCount.Int()'는'reflect : call of reflect.Value.Int on interface Value'라는 패닉을 제공합니다. –

+0

@Amandeepkaur : Go 놀이터에서 작동하는 예제 링크를 사용하여 답장을 편집했습니다. 리플렉션을 잊어 버리면 실제로 상황이 더 복잡해집니다. 타입 어설 션을 사용하는 솔루션에 집중하겠습니다. 맵이 비어 있다면, 아마도'ratingsCountInterface'의 값이 예상과 다릅니다. 전체 소스 코드를 붙여 넣을 수 있습니까? – R3v4n

관련 문제