空のインターフェース (any)
CoddyのGOジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 28/107。
空のインターフェースは、メソッドを0個持つインターフェースです。Goのすべての型には少なくとも0個のメソッドがあるため、すべての型は自動的に空のインターフェースを満たします。これにより、任意の型の値を保持できます。
var anything interface{}
anything = 42
anything = "hello"
anything = true
anything = []int{1, 2, 3}Go 1.18 以降、キーワード any は interface{} のエイリアスとして導入されました。これらは完全に置き換え可能ですが、any のほうが読みやすく簡潔です。
var value any = "Go is awesome"空のインターフェースは、未知の型やさまざまな型の値を扱う必要がある場合に便利です。fmt.Printlnのような関数は、任意の型の引数を受け入れるためにこれを使用します。
func PrintAnything(v any) {
fmt.Println("Value:", v)
}
func main() {
PrintAnything(100)
PrintAnything("text")
PrintAnything(3.14)
}ただし、トレードオフがあります。値を空のインターフェースに格納すると、その具体的な型情報にアクセスできなくなります。
基になる型を先に取り出さないと、メソッドを直接呼び出したりフィールドにアクセスしたりすることはできません。次のレッスンでは、型アサーションと型スイッチを使用して、空のインターフェースから具体的な型を取得する方法を説明します。
チャレンジ
簡単空のインターフェースを使って、任意の型の値を保持できる柔軟なストレージコンテナを構築しましょう。any によって、同じ構造体に異なる型を格納できることを示す、シンプルなボックスを作成します。
コードを2つのファイルに分けて整理します。
box.go: 型がanyの単一のフィールドContentを持つBox構造体を Define します。任意の型の値を accepts し、その値を containing する Box への pointer を returns するNewBoxconstructor function を Create します。ボックスに格納されている内容を示す string を returns するDescribemethod を追加します。main.go: input から異なる値を Read し、integer、string、boolean を containing するボックスを Create した後、各ボックスの説明を Print して、同じ Box type がまったく異なる値を保持できることを示します。
次の input が提供されます。
- Line 1: integer value
- Line 2: string value
- Line 3: boolean value(
trueまたはfalse)
Describe method は、次の format の string を returns する必要があります。
Box contains: [value]たとえば、42、hello、true が与えられた場合、output は次のようになります。
Box contains: 42
Box contains: hello
Box contains: trueここでの重要なポイントは、単一の Box struct が integer、string、または boolean を格納できるということです。これは、any type が任意の type の値を accepts するためです。それぞれのボックスは異なるものを保持しますが、すべて同じ Box type です。
自分で試してみよう
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
reader := bufio.NewReader(os.Stdin)
// 整数値を読み取る
line1, _ := reader.ReadString('\n')
intVal, _ := strconv.Atoi(strings.TrimSpace(line1))
// 文字列値を読み取る
line2, _ := reader.ReadString('\n')
strVal := strings.TrimSpace(line2)
// 真偽値を読み取る
line3, _ := reader.ReadString('\n')
boolVal, _ := strconv.ParseBool(strings.TrimSpace(line3))
// TODO: NewBoxを使用して各値のボックスを作成する
// TODO: Describeメソッドを使用して各ボックスの説明を出力する
// コンパイルエラーを避けるために変数を使用する(実装時にこれらの行を削除する)
_ = intVal
_ = strVal
_ = boolVal
// 出力形式の例:
// fmt.Println(box.Describe())
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
1Go オブジェクト指向の基礎
外部ファイルGo ワークスペースとモジュールパッケージとインポート公開された名前と非公開の名前Go におけるオブジェクト指向入門クラスとしての構造体構造体へのメソッド定義ポインタレシーバと値レシーバ構造体の初期化コンストラクタ関数まとめ:簡易計算機4インターフェース
インターフェース入門暗黙的な実装契約としてのインターフェース空のインターフェース (any)型アサーション型スイッチインターフェースの合成Stringer と Error インターフェースまとめ - 図形計算機8エラー処理とOOP
error インターフェースカスタムエラー型エラーラッピング (fmt.Errorf)センチネルエラーerrors.Is() と errors.As()Panic、Defer、Recover復習 - ファイルパーサー自分で練習してみよう: Goオンラインコンパイラ