
interface型で変数宣言した値を効率よく型アサーションできませんか?
今回は、interface型を効率よく型アサーションする type
についてお伝えしていきます。
マスターするとinterface型を便利に使うことができる便利な機能です。
この記事は、当ブログの「interface型を型アサーションする方法の基本」を前提知識としています。
型アサーションについて自信が無い方は、当ブログの記事を参考にしてください。
【Go言語・interface型】typeとは?
interface型で変数宣言した値を演算などに使用するには、型を断定する型アサーションをする必要があります。
基本的な型アサーションの方法は下記の通りです。
この方法でも問題無いのですが、この方法だとinterface型で変数宣言した値を確認して型アサーションする必要があります。
interface型の「あらゆる型と互換性がある。」の特徴を活かしきれていません。
そこで登場するのが type
です。
typeの下記のように定義します。
typeを使用することで、いろんな型を受け入れることができるのですがこれだけでは機能しません。
typeはswitch文と使用するのが一般的です。
【Go言語・interface型】switch type文で効率的に型アサーション
では、switch type文をプログラムで確認していきましょう。
interface型の型を判別する
// switch type文(interface型の型を判別する)
package main
import "fmt"
func main() {
// 変数宣言
var x interface{} = 100
// switch文を使用して型アサーション
// 型の参照のみ
switch x.(type) {
case int:
fmt.Println("変数xはint型です")
case string:
fmt.Println("変数xはstringです")
case float64:
fmt.Println("変数xはfloat64型です")
default:
fmt.Println("型を参照できませんでした。")
}
}
// 出力結果
$ go run main.go
変数xはintです
switch文とtypeを使い、変数x
の値を判別して結果を出力しています。

では、演習として 変数x
の値を変えてみてswitch type文の動きを確認してみましょう。
typeはswitch文と併用することで、interface型で変数宣言した値の型を判定してくれます。
interface型の型を判定して型アサーションする
では、interface型の型を判定して型アサーションしてみましょう。
// interface型の型を判定して型アサーションする
package main
import "fmt"
func main() {
var x interface{} = 100
// 型アサーション用の変数v
switch v := x.(type) {
case bool:
fmt.Printf("変数vは%tで%Tです。\n", v, v)
case int:
fmt.Printf("変数vは%dで%Tです。\n", v, v)
case string:
fmt.Printf("変数vは%sで%Tです。\n", v, v)
case float64:
fmt.Printf("変数vは%fで%Tです。\n", v, v)
default:
fmt.Println("型を参照できませんでした。")
}
}
// 出力結果
$ go run main.go
変数vは100でintです。

今回はきちんと型アサーションされているか確かめるために Printf
を使いました。
interface型の 変数x
が、変数v
の値が型アサーションされていることが確認できます。
では、次に関数を使用して演算してみましょう。
typeを関数で使って演算する
typeを関数で使って演算してみましょう。
Go言語は通常、関数の引数に型を指定する必要があります。
interface{}
を引数の型に指定することで、どんな型でも引数として扱うことができます。
では、実際に引数の型に interface{}
を指定して、型を判別して型に合った演算を行うプログラムで動きを確認していきましょう。
// typeを関数で使って演算する
package main
import "fmt"
// 関数として使用する
func TestType(a interface{}) {
switch v := a.(type) {
case int:
fmt.Println(v + 1000, "1000を足しました。")
case string:
fmt.Println(v + "はイケメン! 文字列結合しました。")
case float64:
fmt.Println(v - 0.123, "0.123を引きました")
default:
fmt.Println("違う引数でお願いします。")
}
}
func main() {
// TestType関数を実行する
TestType(10)
TestType("もりぴ")
TestType(10.123)
}
// 出力結果
$ go run main.go
1010 1000を足しました。
もりぴはイケメン! 文字列結合しました。
10 0.123を引きました
関数の型を interface{}
にしてswitch type文を関数に利用することで、関数を実行する際の引数の型を意識することなく関数が実行できます。
【参考】if文でtypeを使用する
同じ条件分岐のif文でもtypeを使用することができます。
一般的にはswitch文を使用するので、あくまでも参考としてください。
// if文でtypeを使用する
package main
import "fmt"
func main() {
var x interface{} = 100
// if文を使用して型アサーション
if x == nil {
fmt.Println("None")
} else if i, isInt := x.(int); isInt {
fmt.Println(i)
} else if s, isFloat := x.(float64); isFloat {
fmt.Println(s)
} else {
fmt.Println("変換できませんでした。")
}
}
// 出力結果
$ go run main.go
100
型アサーションの戻り値が2つあることを利用して、if文でtypeを使用しています。

switch type文よりも複雑になるので、使用する機会もほとんどないでしょう。
【まとめ】interface型をtypeを使用して効率的に型アサーション
今回は、interface型をtypeを使用して効率的に型アサーションする方法とswitch type文の利用方法をプログラムを通してお伝えしてきました。
それでは、まとめにはいりましょう。

ちょっと難しかったでしょうか?
かなりプログラミングっぽい内容になったのではないでしょうか。
Go言語のinterface型を使いこなしていきましょう。
comment