【Go】カンマok慣用句(comma ok idiom)について調べてみた

Goで使用するカンマok慣用句(comma ok idiom)について調べてみました。どのようにカンマok慣用句を使うのか、実際にコードを書いて確認します。

カンマok慣用句の使われ方

まずはカンマok慣用句の文法について説明します。

2パターン記載します。1つ目がifの条件式にmapを使用しており、2つ目が条件式に型アサーションを使用しています。調べた限り、主にこの2パターンで使用されています。

1つ目

// mapの作成
f := map[string]int {
	"Apple": 1,
	"Banana": 2,
}

if s, ok := f["Apple"]; ok {
	// do something
}

2つ目

var test interface {}
test = 123

if t, ok := test.(int); ok {
	// do something
}

1つ目:mapで使用されるカンマok慣用句について

これは、mapの中に指定の情報が存在しているかどうかでokに入る情報が変わります。

if s, ok := f["Apple"]; ok {
	// do something
}

これだと、f には"Apple"とそれに紐づく値 1 が定義されているので、返り値として s には 1 が入り、ok には true が入ります。そして、do somethingに書かれた処理を実行します。下記のように記述してみます。

if s, ok := f["Apple"]; ok {
	fmt.Println("--- ok ----")
	fmt.Println(s)
	fmt.Println(ok)
} else {
	fmt.Println("--- not ok ----")
	fmt.Println(s)
	fmt.Println(ok)
}

実行結果です。

--- ok ----
1
true

こんどは"Apple"ではなく"Lemon"に変更してみます。

if s, ok := f["Lemon"]; ok {
	// do something
}

f に"Lemon"は存在していないため、s には int型のゼロ値である 0 が入ります。そして、ok には false がはいります。

--- not ok ----
0
false

2つ目:型アサーションで使用されるカンマok慣用句について

interface{}型の変数はどんな型の値でも格納することができるため型のチェックをします。interface{}型の変数.(型)でチェックすることができます。

var test interface {}
test = 123
if t, ok := test.(string); ok {
	fmt.Println("--- ok ----")
	fmt.Println(t)
	fmt.Println(ok)
} else {
	fmt.Println("--- not ok ----")
	fmt.Println(t)
	fmt.Println(ok)
}

今回、interface{}型のtestに123を代入しています。これはint型なので"test.(int)"のチェック結果は正しいはずです。t には123がはいり、okにはtrueが入ります。では、intじゃなかった場合どうなるでしょうか。

if t, ok := test.(string); ok {
	// do something
}

このように、intをstringに変えました。この結果は正しくないので ok には false が入ります。ただ、t には int のゼロ値ではなくstringのゼロ値 "" が入ります。要は右辺で評価された型のゼロ値が格納されます。

まとめ

このように、mapと型アサーションにおいて値のチェックをする際はカンマok慣用句を使用するとチェックが簡単にできます。