ヒント
空のインターフェイス型は、 C#またはJava言語の Object、C 言語の void*、 C++の std::any に似ています。ジェネリックスとテンプレートが登場する前は、空のインターフェイスはデータ抽象化の保存と使用のための非常に柔軟な方法でした。
空のインターフェイスの内部実装は、オブジェクトのタイプとポインターを保持します。空のインターフェイスを使用してデータを保存するプロセスは、データに対応する型の変数を使用して直接保存する場合よりも若干遅くなります。したがって、開発では、どこでもではなく、必要に応じて空のインターフェイスを使用する必要があります。
値を空のインターフェースに保存する
空のインターフェイスの割り当ては次のとおりです。
var any interface{}
any = 1
fmt.Println(any)
any = "hello"
fmt.Println(any)
any = false
fmt.Println(any)
コード出力は次のとおりです。
1
hello
false
コードの説明:
- 1 行目では、any を typeinterface{} の変数として宣言しています。
- 3行目ではanyに整数1が代入されています。
- 4 行目では、any の値が出力されますが、fmt.Println に提供される型は依然としてインターフェイス{}です。
- 6 行目では、文字列 hello を any に割り当てます。この時点で、any は内部的に文字列を保存します。ただし、タイプは依然としてインターフェース{}です。
- 9 行目はブール値を割り当てます。
空のインターフェースから値を取得する
空のインターフェイスに保存された値を指定された型から直接取得すると、コンパイル エラーが発生します。コードは次のとおりです。
// 声明a変数、型int、初期値は1
var a int = 1
// 声明i変数、型はinterface{}、初期値はa、この時点でiの値は1になる
var i interface{} = a
// 声明b変数、iに代入を試みる
var b int = i
8行目のコードコンパイルエラー:
cannot use i (type interface {}) as type int in assignment: need type assertion
コンパイラは、変数 i を int 型であるかのように b に割り当てることはできないと通知します。
コードの 15 行目で、a の値が i に代入されると、代入後の i の内部値は int になりますが、i は依然としてinterface{} 型の変数です。容器にお茶やタバコを入れても同様に、容器は金属製であるため、内容物の種類が変わっても変化しません。
8 行目の操作を完了するために、コンパイラは型アサーション (型アサーション) を使用するように求めます。
次のように、型アサーションを使用するように 8 行目を変更します。
var b int = i.(int)
変更後、コードをコンパイルして渡すことができ、b は変数 i: 1 に格納されている変数 a の値を取得できます。
空のインターフェイスがさまざまな値を保存した後、 ==
使用して他の変数値と同様に比較演算を実行できます。空のインターフェイスの比較には次の特性があります。
1) 異なるタイプの空のインターフェイス間の比較結果は同じではありません
異なる型の値を保持する空のインターフェイスを比較する場合、Go 言語は最初に値の型を比較します。したがって、型が異なり、比較結果も異なります。コードは次のようになります。
// a saves an integer
var a interface{} = 100
// b saves a string
var b interface{} = "hi"
// Two empty interfaces are not equal
fmt.Println(a == b)
コード出力は次のとおりです。
false
2) 空のインターフェースでは動的値を比較できません
動的タイプの値がインターフェイスに格納されている場合、実行時にエラーがトリガーされます。コードは次のとおりです。
// c保存包含10的整型切片
var c interface{} = []int{10}
// d保存包含20的整型切片
var d interface{} = []int{20}
// ここでクラッシュが発生します
fmt.Println(c == d)
コードは 8 行目でクラッシュします。
panic: runtime error: comparing uncomparable type []int
これは、[]int が比較できない型であることを示す実行時エラーです。次の表に、いくつかのタイプと比較を示します。
タイプ | 説明する |
---|---|
map | ダウンタイムエラー、比較対象外 |
slice([]T) | ダウンタイムエラー、比較対象外 |
channel | 比較可能、同じメーカーによって生成される必要があります。つまり、同じチャネルが true になります。それ以外の場合は false になります。 |
array([容量]T) | 比較可能、コンパイル時は 2 つの配列が一貫しているかどうかを認識します。 |
struct | Comparable、構造体の値を 1 つずつ比較できます |
func | 匹敵します |