カランのブログ

ソフトウェアエンジニア / 台湾人 / 福岡生活

今のモード ライト

golangでは、interface{}型に対して型アサーションを行うことで、そのインターフェースが特定の型であると仮定して、その型のメソッドを操作することができます。

var i interface{} = "hello"
s := i.(string)
fmt.Println(s)

このコードは、元々のinterface{}を文字列にアサーションします。

ただし、注意しなければならないのは、この型が文字列でない場合、このコードは直接パニックを引き起こします。

args := []interface{}{
		1,
		"1",
		"2",
	}
for _, arg := args {
  val := arg.(int) // interface conversion: interface {} is string, not int
  fmt.Println(val)
}

golangは、型アサーションが2つの値を返すメカニズムを提供しており、1つは変換後の値で、もう1つはアサーションが正しいかどうかです。

args := []interface{}{
		1,
		"1",
		"2",
	}
for _, arg := args {
  if val, ok := arg.(int); ok {
    fmt.Println(val)    
  } else {
    fmt.Println("not int.")
  }
}

ここで注意する必要があるのは、

  1. 第2の戻り値がない場合、型が確定していない限り、アサーションの失敗によりパニックが発生する可能性があることです。
  2. 第2の戻り値を追加すると、パニックは発生しません。

少し手間がかかるかもしれませんが、常に型変換を行う方が安全です。

また、注意しなければならない点は、アサーションが失敗した場合のvalは、アサーションした型のゼロ値になるということです。

アサーションが失敗した場合のvalは、アサーションした型のゼロ値になります。

for _, arg := range args {
  if val, ok := arg.(int); ok {
    fmt.Println(val, ok) // 1, true
  } else {
    fmt.Println(val, ok) // 0 , false
    // 0, false
  }
}

一般的に、アサーションが失敗した後、この値を使用することはあまりありませんが、うっかりするとトラップにはまることがあります。

次の記事

Goworker 入門 — Redis によるワーカーの実装

前の記事

golangアプリでログを収集して一元化する方法

この文章が役に立つと思うなら、下のリンクで応援してくれると大変嬉しいです✨

Buy me a coffee

作者

Kalan 頭像照片,在淡水拍攝,淺藍背景

愷開 | Kalan

Kalan です。台湾出身で、2019年に日本へ転職し、福岡に住んでいます。フロントエンド開発に精通しているだけでなく、IoT、アプリ開発、バックエンド、電子工作などの分野にも挑戦しています。 最近、エレキギターを始めました。ブログを通じて、より多くの人と交流できればと思っています。気軽に絡んでください