switch typeでinterface型を型アサーションしよう!

Go言語
この記事は約7分で読めます。
Go初学者
Go初学者

interface型で変数宣言した値を効率よく型アサーションできませんか?

この記事ではinterface型を効率よく扱うtypeについて理解できます!
  • typeとは?
  • typeを使ってinterface型を効率よく型アサーションする方法(switch type文)
  • typeを関数で使ってみる
  • 参考としてif文でtypeを使ってみる

今回は、interface型を効率よく型アサーションする type についてお伝えしていきます。

マスターするとinterface型を便利に使うことができる便利な機能です。

この記事は、当ブログの「interface型を型アサーションする方法の基本」を前提知識としています。

型アサーションについて自信が無い方は、当ブログの記事を参考にしてください。

もりぴ
この記事を書いた人

XHTML1.0時代にHTML&CSSを勉強した経験あり。無趣味だった私が2020年5月からプログラミング学習を開始し現在も挫折せずに趣味で学習を楽しんでいる51歳。プログラミングの楽しさをブログを通してお伝えしていきます。

もりぴをフォローする

【Go言語・interface型】typeとは?

interface型で変数宣言した値を演算などに使用するには、型を断定する型アサーションをする必要があります。

基本的な型アサーションの方法は下記の通りです。

型アサーションする変数 = interface型で宣言した変数.(型)

この方法でも問題無いのですが、この方法だとinterface型で変数宣言した値を確認して型アサーションする必要があります。

interface型の「あらゆる型と互換性がある。」の特徴を活かしきれていません。

そこで登場するのが type です。

typeの下記のように定義します。

型アサーションする変数 = interface型で宣言した変数.(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文の利用方法をプログラムを通してお伝えしてきました。

それでは、まとめにはいりましょう。

この記事で覚えておくことのまと
  • typeを使用することでinterface型を効率よく型アサーションすることができる
  • typeの定義 型アサーションする変数 = interface型で宣言した変数.(type)
  • typeは、switch文と併用するのが一般的
もりぴ
もりぴ

ちょっと難しかったでしょうか?

かなりプログラミングっぽい内容になったのではないでしょうか。

Go言語のinterface型を使いこなしていきましょう。

comment

タイトルとURLをコピーしました