interface型を型変換(型アサーション)の基本

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

Go言語のinterface型を型変換する方法ってあるの?

この記事ではGo言語のinterface型の型変換の基本を理解できます!
  • interface型の型変換(型アサーション)の基本について
  • interface型の型変換(型アサーション)の注意点について

Go言語のinterface型で変数宣言すると、変数を利用した演算等に利用できません。

それでは不便ですので、interface型から他の型へ型変換(型アサーション)するための基本をお伝えしていきます。

interface型について、まだ理解が曖昧な時は当ブログの記事を参考にしていください。

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

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

もりぴをフォローする

【Go言語のinterface型】型変換(型アサーション)の基本

Go言語のinterface型を型変換するというよりも、型を断定するという表現が正しいでしょう。

例えば、inteface{} に 数字の 10 を代入した場合、この 10int型 として断定する。

といった感じです。

MEMO

interface型の型を断定することを「型アサーション」といわれています。

もりぴ
もりぴ

ここから先は「型アサーション」でお伝えしていきます。

interface型を型アサーションする

型アサーションのやり方は、通常の型変換とちょっとだけ違いがあります。

型アサーションする変数 = interface型で宣言した変数.(型)
. の付け忘れ注意!

ここで注意するのが、 . を忘れないことです。

それでは、プログラムで確認していきましょう。

// interface型を型アサーションする
package main

import "fmt"

func main() {
    // interface型で変数宣言
    var a interface{} = 10
    // 型変換用の変数宣言
    var b int

    // interface{}型の値の型を参照して、型変換する
    b = a.(int)

    // 型を確認してみる
    fmt.Printf("a = %d\t%T\n", a, a)
    fmt.Printf("b = %d\t%T\n", b, b)
}
// 出力結果
$ go run main.go 
a = 10  int
b = 10  int
Go初学者
Go初学者

あれ?!変数ainterface{} ではなくて、int なんですね。

interface型は、代入した値によって動的に型を決めています。

しかし、このままでは演算などの処理に使用できないため型アサーションが必要になるのです。

interface型を型アサーションした変数で演算する

では、型アサーションした変数で演算してみましょう。

まずは型アサーションしない場合の演算を確認してみます。

// interface型を型アサーションする
package main

import "fmt"

func main() {
    // interface型で変数宣言
    var a interface{} = 10
    // 型変換用の変数宣言
    var b int

    // interface{}型の値の型を参照して、型変換する
    b = a.(int)

    // 型を確認してみる
    fmt.Printf("a = %d\t%T\n", a, a)
    fmt.Printf("b = %d\t%T\n", b, b)

    // 型アサーションしていない変数aで演算
    fmt.Println(a + 1)
}
// 出力結果
$ go run main.go 
# command-line-arguments
./main.go:24:19: invalid operation: a + 1 (mismatched types interface {} and int)

「型が不一致なので演算できない」という内容のエラーになりました。

では、型アサーションした 変数b で演算してみます。

// interface型を型アサーションする
package main

import "fmt"

func main() {
    // interface型で変数宣言
    var a interface{} = 10
    // 型変換用の変数宣言
    var b int

    // interface{}型の値の型を参照して、型変換する
    b = a.(int)

    // 型を確認してみる
    fmt.Printf("a = %d\t%T\n", a, a)
    fmt.Printf("b = %d\t%T\n", b, b)

    // 型アサーション済みなので演算可能
    fmt.Printf("b + 3 = %d\n", b + 3)
}
// 出力結果
$ go run main.go 
a = 10  int
b = 10  int
b + 3 = 13

エラーが出ずに演算ができています。

【Go言語のinterface型】型変換(型アサーション)の注意点

interface型は、代入した値によって動的に型を決めています。

先程お伝えしたことですが、ここで今までのプログラムを活用してint型ではなく float64 に型アサーションしてみましょう。

// 型アサーションの注意点のテスト
package main

import "fmt"

func main() {
    // interface型で変数宣言
    var a interface{} = 10

    // 変数aをfloat64型に変換したらどうなる?
    var fl float64
    fl = a.(float64)
    fmt.Println(fl)
}
// 出力結果
$ go run main.go 
panic: interface conversion: interface {} is int, not float64

panic エラーになりプログラムが強制終了されます。

型アサーションでpanicエラーを回避する

型アサーションには2つの戻り値が用意されています。

型アサーション・2つの戻り値
  1. 型アサーションした値
  2. 型アサーション成功した場合は true 失敗の場合は false を返す

では、プログラムで確認していきましょう。

// 型アサーションでpanicエラーを回避する
package main

import "fmt"

func main() {
    // interface型で変数宣言
    var a interface{} = 10

    // 変数aをfloat64型に変換したらどうなる?
    var fl float64

    // 戻り値を2つ受け取る
    fl, isFloat := a.(float64)
    fmt.Println(fl, isFloat)
}
// 出力結果
0 false

panicエラーを回避して、float64 の初期値 0 と型アサーション失敗の false が出力されています。

【まとめ】Go言語のinterface型・型アサーションについて

今回はGo言語のinterface型の型アサーションについてお伝えしていきました。

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

Go言語のinterface型の型アサーションで押さえておくこと!
  • interface型の型を断定することを「型アサーション」という
  • 型アサーションの方法(. の付け忘れ注意!)
    型アサーションする変数 = interface型で宣言した変数.(型)
  • interface型は、代入した値によって動的に型を決まる
  • 型アサーションには2つの戻り値が用意されている
    1. 型アサーションした値
    2. 型アサーション成功した場合は true 失敗の場合は false を返す

以上です。

今回お伝えしてきた内容では、プログラムとしては不十分です。

それは、interface型で動的に決定した型を自動で判別できていません。

これでは、一回一回確認しながらコードを書く必要があります。

それを回避するために、条件分岐を活用してinterface型の型アサーションしていくプログラムがあります。

当ブログの下記の記事を参考にしてくださいね。

comment

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