先日のgolang.tokyoではswitch
文に関するDevquizが出題された。
私はわかっていたつもりで乾杯の挨拶中に解説を話したが、間違えた解説だったので改めて仕様を確認した。
TL;DR
- 先日のgolang.tokyoのDevquizの解説で誤った解説をしてしまった
- https://golangtokyo.connpass.com/event/151926/
- Devquizは
switch ok := false; {...}
というswitch
文の挙動について
- Goの
switch
文は条件以外に、switch
内にスコープを絞ったStatement
を書くことができる。switch x := f(); x { ... }
- Goの
switch
文は条件(タグ)なしで書くことができる- タグなし
switch
(tagless-switch
)はswitch true
- タグなし
正しい答えは@makki_dさんに会場でも指摘してもらった。
クイズのswitch文、ok:=falseの後のセミコロンの後が空なのが味噌だよね#golangtokyo
— MakKi (@makki_d) November 5, 2019
golang.tokyo #27のDevquiz
2019/11/05に行われたgolang.tokyoの抽選では以下のDevquizが出題された。
// 以下のコードを実行すると何が出力されるか答えよ。
package main
import "fmt"
func main() {
switch ok := false; {
case true:
fmt.Println("true", ok)
case false:
fmt.Println("false", ok)
default:
fmt.Println("default")
}
}
何が出力されるかというと、true false
が出力される。
私はこれを「case true
が常に真として評価されるからtrue false
が出力される。」と解説したがそれは誤りだった。
switch文の言語仕様について
switch
文の言語仕様は以下で確認することができる。
- Switch statements | The Go Programming Language Specification
Devquizのswitch
文はtype switch
ではないので、ExprSwitchStmt
となる。
SwitchStmt = ExprSwitchStmt | TypeSwitchStmt .
ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" .
switch
内にスコープを絞ったStatementを書ける
ExprSwitchStmt
の定義を見ればわかる通り、switch
文は実際にswitch
文で評価したい式(Expression
)と別に代入などの文(SimpleStmt
)を含むことができる。
Devquiz中のswitch
文もSimpleStmt
として、代入式を含んでいた
switch ok := false; {
Goのswitch
文は式(タグ)なしで書くことができる
わかる人はもうわかっただろうが、Devquizのswitch
文には式が含まれていない。これはGoの文法的に間違いではない。
There can be at most one default case and it may appear anywhere in the “switch” statement. A missing switch expression is equivalent to the boolean value true.
式が含まれていないswitch
文はswitch true
として条件評価が行われる。
よって、 今回のDevquizは「switch true
というswitch
文だったので、case true:
という条件が真になっていた」のが正しい解説となる。
switch ok := false; ok {
と書けばok
変数の値と各case
の値が比較され、(人間がパット見考える)期待どおりの挙動となる。
なお、switch {...}
のような、式がないswitch
文のことを、“タグなしswitch
"(tagless-switch
)と呼ぶ。
タグなしswitch
の評価がswitch true
になることはプログラミング言語Goでもしっかり明記されている。
終わりに
2,3か月に1回くらいの割合でGoの言語仕様を読んでいる気がする。
Goの言語仕様はこの1ページだけだし、文中のキーワードにはリンクが付いているので勉強しやすい。
毎回忘れてやり直している気がするが、Expression
とStatement
の違いも頭に入ってきた。