Golang のリフレクションを使用すると、プログラムは実行時にデータ構造、型、値を調べて変更できます。これは、実行時に変数の型と値を調べ、型の新しいインスタンスを作成し、既存の変数の値を変更できる一連の関数を提供します。この記事では、reflect パッケージのさまざまな Golang 関数について説明します。
目次
- Go にパッケージを反映する
- 関数reflect.Copy()
- 関数refref.DeepEqual()
- Reflect.Swapper() 関数
- 関数reflect.TypeOf()
- Reflect.ValueOf() 関数
- 結論
Go は静的に型指定された言語であるため、変数の型はコンパイル時にわかっている必要があります。ただし、特定のシナリオでは、プログラムが実行されるまで型が決定できない値を処理する必要がある場合があります。
たとえば、さまざまな型の引数を処理できる関数を作成する必要がある場合や、未知の型のデータをシリアル化および逆シリアル化する必要がある場合があります。 Golang では、reflect パッケージが使用されます。
Go にパッケージを反映する
Reflect パッケージは、値の型に関係なく、実行時に値を検査および操作できる一連の関数を提供します。これらの関数を使用すると、変数の型と値に関する情報を取得し、型の新しいインスタンスを作成し、既存の変数の値を変更できます。
Golang のリフレクト パッケージには 2 つのタイプが含まれています。 タイプと値。 Type は、int、string、カスタム構造体などの Go の型を表します。値は、42 や「hello」など、特定のタイプの値を表します。
Reflect パッケージには、変数から Type オブジェクトと Value オブジェクトを取得できる一連の関数も提供されています。たとえば、reflect.TypeOf() 関数は変数の型を表す Type オブジェクトを返しますが、reflect.ValueOf() 関数は変数の値を示す Value オブジェクトを返します。
次のセクションでは、reflect パッケージで一般的に使用される関数のいくつかを検討します。
関数reflect.Copy()
Reflect パッケージの Reflect.Copy() 関数は、あるスライスの値を別のスライスにコピーするために使用されます。これは 2 つのパラメータ dst と src を受け取り、両方とも同じ要素タイプのスライス値である必要があります。この関数は、src スライスから dst スライスに値をコピーし、コピーされた要素の数を返します。
以下の例では、reflect.Copy() 関数を示します。
パッケージ 主要輸入 (
「fmt」
'反射'
)
機能 主要 () {
送信元 := [] 整数 { 1 、 2 、 3 、 4 、 5 }
夏時間 := 作る ([] 整数 、 それだけ ( 送信元 ))
n := 反射 。 コピー ( 反射 。 値の ( 夏時間 )、 反射 。 値の ( 送信元 ))
fmt 。 プリントイン ( n ) // 出力: 5
fmt 。 プリントイン ( 夏時間 ) // 出力: [1 2 3 4 5]
}
この例では、いくつかの整数値を含むソース スライス src と、src と同じ長さのデスティネーション スライス dst を作成します。次に、reflect.Copy() を呼び出して src から dst に値をコピーし、コピーされた要素の数 (n) と dst スライスの内容を出力します。
関数refref.DeepEqual()
2 つの値が等しいかどうかを比較するために、reflect パッケージのreflect.DeepEqual() 関数が使用されます。この関数には、a と b という 2 つの入力パラメータがあり、どちらも任意の型の任意の値にすることができます。 a と b が完全に等しい場合、この関数は true を返します。これは、それらの基礎となる値が再帰的に等しいことを意味します。そうでない場合、それは偽であることが判明します。
次の例は、reflect.DeepEqual() の使用方法を示しています。
パッケージ 主要輸入 (
「fmt」
'反射'
)
機能 主要 () {
ある := [] 整数 { 1 、 2 、 3 }
b := [] 整数 { 1 、 2 、 3 }
もしも 反射 。 ディープイコール ( ある 、 b ) {
fmt 。 プリントイン ( 「aとbは等しい」 )
} それ以外 {
fmt 。 プリントイン ( 「aとbは等しくない」 )
}
}
この例では、同じ整数値を持つ 2 つのスライス a と b を作成します。次に、reflect.DeepEqual() を呼び出して a と b が等しいかどうかを比較し、結果を出力します。
Reflect.Swapper() 関数
Reflect パッケージの Reflect.Swapper() 関数は、スライスの要素を交換できる関数を返すために使用されます。単一のパラメータ v を受け取りますが、これはスライス値である必要があります。この関数は、2 つの整数パラメーター i と j を受け取り、位置 i と j でスライスの要素を交換する関数を返します。
Reflect.Swapper() の使用法は、次の例で説明できます。
パッケージ 主要輸入 (
「fmt」
'反射'
)
機能 主要 () {
s := [] 整数 { 1 、 2 、 3 、 4 、 5 }
スワップ := 反射 。 スワッパー ( s )
スワップ ( 1 、 3 )
fmt 。 プリントイン ( s ) // 出力: [1 4 3 2 5]
}
この例では、いくつかの整数値を含む s という名前のスライスを作成しました。次に、reflect.Swapper() を呼び出して、スライスの要素を交換できる関数 swap を取得します。 swap を使用して、s スライスの位置 1 と 3 の要素を交換し、結果を出力します。
関数reflect.TypeOf()
値の型を取得するには、reflect.TypeOf() を使用します。この関数は、任意の型または値の単一パラメータ「v」を受け入れます。この関数は、値の型を表すreflect.Type値を返します。
Reflect.TypeOf() の使用法は、次の例で説明できます。
パッケージ 主要輸入 (
「fmt」
'反射'
)
機能 主要 () {
だった バツ float64 = 3 。 14
t := 反射 。 タイプの ( バツ )
fmt 。 プリントイン ( t ) // 出力: float64
}
この例では、値 3.14 を持つ float64 変数 x を作成します。次に、reflect.TypeOf() を呼び出して x の型を取得し、結果をreflect.Type 変数 t に保存します。 t の値 (float64) を出力します。
Reflect.ValueOf() 関数
Reflect.ValueOf() は、値の Reflect.Value 表現を取得できます。単一のパラメータ v を受け取ります。これには、任意の型の任意の値を指定できます。この関数は、入力パラメータの値を表すreflect.Value値を返します。
Reflect.ValueOf() の使用法は、次の例で説明できます。
パッケージ 主要輸入 (
「fmt」
'反射'
)
機能 主要 () {
だった バツ float64 = 3 。 14
の := 反射 。 値の ( バツ )
fmt 。 プリントイン ( の ) // 出力: 3.14
}
この例では、値 3.14 を持つ float64 変数 x を作成します。次に、reflect.ValueOf() を呼び出して x のリフレクト値表現を取得し、その結果をリフレクト値変数 v に保存します。v の値 (3.14) を出力します。
Reflect パッケージは、ここで説明したもの以外にも多数の機能を提供します。これらはほんの数例です。リフレクト パッケージによって提供される関数を使用すると、コンパイル時に型を知る必要がなく、任意の型の値を処理できるコードを作成できます。
結論
Golang のリフレクションを使用すると、プログラムは実行時にデータ構造、型、および値を調べて変更できます。これは、型と値を検査および操作する機能を提供するリフレクト パッケージを通じて実装されます。リフレクションは、インターフェイスや未知の型を操作する場合、または汎用関数を実装する必要がある場合に特に役立ちます。この記事では、reflect パッケージ、reflect Type と Value、動的な型と値など、Golang のリフレクションの基本について説明しました。