2017-09-27 14 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フレームワークを使用してHTTPリクエストをAPIに送ります。

問題は、変数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()を使用する必要があります。

しかし、前にも述べたように、リフレクションは使用しないでください。アサーションタイプの最初のソリューションを使用し、ちょうど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 Playgroundの作業例へのリンクを使って返信を編集しました。反射については忘れてしまい、実際にはもっと複雑になります。タイプアサーションを使用する私のソリューションに注目しましょう。マップが空の場合、 'ratingsCountInterface'の値はおそらくあなたが期待していない値です。ソースコード全体を貼り付けることはできますか? – R3v4n

関連する問題