interface{}型
【開発環境】
OS:Win11(64ビット)
go version go1.19.4 windows/amd64
VSCode1.72.2、及びコマンドプロンプト
【interface{}型とは】
通常、変数を宣言する時には型もセットで宣言する必要がありますが、interface型を使用すると型にとらわれずに値を代入することができます。
ただし、通常の変数は変数の型が合っていれば足し算などの演算に使用できますが、interface型は演算には使用できません。
例文
//interface型の関数宣言
func Cry(any interface{}) {
any.Cry()
}
// 構造体Bookの宣言
type Book struct{}
//book変数を作る
book := new( Book)
Cry(book)
しかし、本は鳴かないので先程の関数Cry()を呼び出すことができない!
そこで、anyがインターフェースAnimalを満たす場合だけ、Animal.Cry()を呼び出すようにする必要があります。
そのためには、型アサーションと呼ぶ「any.(Animal)」を使う
//Cry - なんでも鳴くものはなくなくし鳴かない者は鳴かない
func Cry(any interface{}) {
a,ok := any.(Animal) //Animalであるか調べる
if !ok {
fmt.println("鳴かないよ")
return
}
a.Cry()
}
any.(Animal)は、anyがAnimalを満足する時(Dog、Catの場合)、aにAnimalを満足するポインターを返し、OKにはtrueを返す。anyがAnimalを満足しない時(bookの場合)、aにnilポインターを返す。OKにはfalseを返します。
・サンプルコード
//animal3.go
package main
import "fmt"
//Animal - 動物のインターフェース
type Animal interface {
Cry()
}
//Dog - 犬の構造体
type Dog struct{}
//Cry - 犬が吠える
func (d *Dog) Cry() {
fmt.Println("わんわん")
}
//Cat - 猫の構造体
type Cat struct{}
//Cry - 猫が鳴く
func (c *Cat) Cry() {
fmt.Println("にゃーご")
}
//Book - 本の構造体
type Book struct{}
//Cry - 何でも鳴くものは鳴くし鳴かないものは鳴かない
func Cry(any interface{}) {
a, ok := any.(Animal) //Animalで調べる
if !ok {
fmt.Println("鳴かないよ")
return
}
a.Cry()
}
func main() {
//犬と猫を作る
dog := new(Dog)
cat := new(Cat)
//犬と猫がなく
Cry(dog)
Cry(cat)
//本を作る
book := new(Book)
Cry(book) //本は鳴かない
}
・実行
PS D:\GO言語\サンプルプログラム\Go-7\インターフェース> go run animal3.go
わんわん
にゃーご
鳴かないよ