定数生成器 iota についてちゃんと書く
「第16回『プログラミング言語Go』オンライン読書会」で出た話題を過去の失敗を含めて Zenn で書いたが,微妙に反応がある気がするので,今後の自分のためにも iota
1 についてちゃんと書いておいたほうがいいかもしれない。
まずは用語から入るとしよう。
定数の中でも rune
,整数(int
など),浮動小数点数(float64
など),複素数(complex128
など)の定数をまとめて「数値定数(numeric constants)」と呼ぶ。
数値定数の定数式(constant expression)は以下のようにリテラルで表すことができる。
package main
import "fmt"
const (
Rune = 'a'
Integer = 1 << 2
FloatingPont = 3.4
Complex = 5.6 + 7.8i
)
func main() {
fmt.Println(Rune, Integer, FloatingPont, Complex) // 97 4 3.4 (5.6+7.8i)
}
(型付けなし定数(untyped constant)として宣言されている点に注意)
定数生成器(constant generator)iota
は数値定数の中で事前に宣言された型付けなし整数を表す識別子で,以下の性質を持つ。
強調は私がやりました。
ポイントは iota
は(const (...)
内の)インデックス値であってカウンタではないということだ。
私が過去にやらかした勘違いについて敢えて解説すると,もともと定数宣言は
という性質があり,同じ定数式の繰り返しを省略することができる。
package main
import "fmt"
const (
c1 = 1
c2
c3
)
func main() {
fmt.Println(c1, c2, c3) // 1 1 1
}
これとインデックス値 iota
を組み合わせて
package main
import "fmt"
const (
c1 = 1 + iota
c2
c3
)
func main() {
fmt.Println(c1, c2, c3) // 1 2 3
}
のように書けるのだが,この字面から何となく iota
をカウンタと思い込んでいたのだった。
嗚呼,恥ずかしい…
上の定数宣言は以下と等価である。
const (
c1 = 1 + iota // c1 == 1 (iota == 0)
c2 = 1 + iota // c2 == 2 (iota == 1)
c3 = 1 + iota // c3 == 3 (iota == 2)
)
また ConstSpec 単位のインデックス値なので,こんな変態的な記述もできる(笑)
というわけで,どっとはらい。
参考図書
- プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)
- Alan A.A. Donovan (著), Brian W. Kernighan (著), 柴田 芳樹 (翻訳)
- 丸善出版 2016-06-20
- 単行本(ソフトカバー)
- 4621300253 (ASIN), 9784621300251 (EAN), 4621300253 (ISBN), 9784621300251 (ISBN)
- 評価
著者のひとりは(あの「バイブル」とも呼ばれる)通称 “K&R” の K のほうである。この本は Go 言語の教科書と言ってもいいだろう。
-
ちなみに iota は「イオタ」と読む。ギリシャ文字のイオタ(Ι / ι)を指す言葉である。 ↩︎