web-dev-qa-db-ja.com

map [string] interface {}とinterface {}の違い

JSONファイルをmap[string]interface{}に解析したい:

var migrations map[string]interface{}
json.Unmarshal(raw, &migrations)

fmt.Println(migrations["create_user"])

しかし、データをinterface{}にポイントするようにコードを変更しました:

var migrations interface{}
json.Unmarshal(raw, &migrations)

// compile wrong here
fmt.Println(migrations["create_user"])

上記の場合のmap[string]interface{}interface{}の違いについてはよくわかりません。

5
Trần Kim Dự

これは、デフォルトでmap [string] interface {}の基になる値を取得するためにassert interface {}を入力する必要があるためです。

GoLang 仕様に従って

インターフェイスタイプとタイプTの式xの場合、1次式

x.(T)

xがnilではなく、xに格納されている値がT型であることを表明します。表記x。(T)は、型表明と呼ばれます。

また、Unmarshal関数には、タイプインターフェース{}またはマップ[文字列]インターフェース{}のmigrationへのポインターが必要です。

var migrations interface{}
json.Unmarshal(raw, &migrations)

fmt.Println(migrations.(interface{}).(map[string]interface{})["create_user"])

migrationsはマップではないため。したがって、そのキーを使用して値を取得することはできません。インターフェース{}にはキーがありません

6
Himanshu

これら2つのタイプの違いは、見た目だけです。

  1. interface{}は「任意」のタイプです。これは、allタイプが関数なしのインターフェースを実装するためです。

  2. map[string]interface{}は、キーが文字列で値が任意のタイプのマップです。

JSONからメモリにバイト配列を非整列化する場合、interface{}タイプを使用するのが最も簡単です。これは、JSONドキュメントの任意のタイプ(オブジェクト、配列、プリミティブなど)を格納できるためです。ただし、基になるデータを処理するには、より多くのリフレクションが必要になる場合があります。 JSONドキュメントがオブジェクトであることがわかっている場合はmap[string]interface{}を使用し、ドキュメントが配列であることがわかっている場合は[]interface{}を使用するのが一般的です。

ただし、JSONを非整列化するための最良のアプローチ(特に、事前にドキュメントの構造がわかっている場合)は、データを正確に記述するカスタム構造体型を定義して使用することです。このようにして、反射を避け、コードの読みやすさを向上させることができます。

11
maerics