· 2分で読了
Golang ノート — Type Assertion
この記事は中国語から自動翻訳されたものです。翻訳によりニュアンスが失われている場合があります。
Go言語(golang)において、interface{} 型に対しては型アサーション(Type Assertion)を行うことで、その interface が特定の型であると仮定し、その型のメソッドを操作できるようになる。
var i interface{} = "hello"
s := i.(string)
fmt.Println(s)
このコードは、元の interface{} を文字列としてアサーションできる。
ただし特に注意が必要なのは、もしこの型が文字列でない場合、このコードは即座に panic を引き起こす点だ。
args := []interface{}{
1,
"1",
"2",
}
for _, arg := args {
val := arg.(int) // interface conversion: interface {} is string, not int
fmt.Println(val)
}
Go言語にはある仕組みが用意されており、型アサーションは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.")
}
}
ここまでのところで、注意すべき点が2つある:
- 2つ目の戻り値を受け取らない場合、型を完全に確信していない限り、アサーション失敗によってプログラムが panic を起こす可能性がある
- 2つ目の戻り値を追加すれば、
panicは発生しない
少し面倒ではあるが、やはり常に安全側に倒して型変換を行うのが無難だ。
もう1点注意すべきなのは、アサーションに失敗した後の val は、アサーションしようとした型のゼロ値(zero-value)になるということだ。
アサーション失敗後の 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
}
}
一般的にはアサーション失敗後にこの value を使うことはあまりないが、油断していると落とし穴にハマるかもしれない。
関連記事
- 測定が目標になるとき:窓税からPull Request数まで かつて僕は小さなツールを自作し、四半期で自分がどれだけPRに貢献したか、レビューコメントをどれだけ残したか、チケットをどれだけ消化したかを集計して、上司にアウトプットを証明しようとしたことがある。上司は淡々と、評価はアウトプットだけで見るものではないと言った。数年後、僕はようやく理解した――測定が目標になるとき、それはもはや良い測定ではなくなるのだ。英国の窓税、ハノイのネズミ駆除の報奨金から、現代のPR数による開発者評価に至るまで、そのメカニズムはまったく同じだ。
- Cloudflare Images を画像ストレージ・変換ソリューションとして使う ウェブページに画像を1枚置くのはフロントエンドにとって最も簡単なことだが、リサイズや各種フォーマットの生成、さらにはトラフィックの負荷に耐えることまで完璧にやろうとすると、実際には一つの包括的なソリューションが必要になる。僕はその後、すべて Cloudflare Images に任せるようになり、オリジナル画像1枚だけを渡すようにしている。
- もう AWS Access Key を使うのはやめよう Access Key は AWS において見落とされがちなセキュリティリスクだ。OIDC と IAM Role を組み合わせることで、GitHub Actions にシークレットを一切保持させることなく、安全に AWS リソースを操作できるようにする。
- データベース主キー:AUTO_INCREMENT、UUID、そしてUUIDv7 バックエンド開発で度々直面する主キーの決定。auto incrementを使うべきか、それともUUIDか?衝突への懸念は?UUIDv7とcreated_at + インデックスの性能差はどれほどか?実際に2,000万件のデータで検証したベンチマークと設計上の意思決定を解説する。