Go AdventCalendar2016の9日目(2016/12/09)の記事です。
前の記事は massa142さんの「Hacker Newsを一覧表示してくれるCLIツールを書いた」でした。
はじめに
ちょっとマイナーなGolangの言語仕様である、iotaについて紹介します。
結構入門書とかにも書いてあるんですが、読み飛ばしがちなんですよね。
特に新規性がある内容ではないので、タイトルでもう知ってるわ!という方はそっ閉じしてもらって大丈夫です。
iotaとは
iotaは、定数宣言(const)の内での既定された識別子です。
型なしの整数の連番を生成します。具体例を見ましょう。
package main
import "fmt"
const (
zero = iota
one = iota
two = iota
three = iota
)
func main() {
fmt.Printf("zero:%v\n", zero)
fmt.Printf("one:%v\n", one)
fmt.Printf("two:%v\n", two)
fmt.Printf("three:%v\n", three)
}
https://play.golang.org/p/9uycXahdRE
結果はこうです。
zero:0
one:1
two:2
three:3
最初の1つのみ設定しておけば、あとは省略することが可能です。
(ちなみにこれはiotaに限らず、定義する値を省略すると、直前に定義されたものが流用されます。)
package main
import "fmt"
const (
zero = iota
one
two
three
)
func main() {
fmt.Printf("zero:%v\n", zero)
fmt.Printf("one:%v\n", one)
fmt.Printf("two:%v\n", two)
fmt.Printf("three:%v\n", three)
}
ConstSpec毎にインクリメントされ、次の予約語constが現れたらリセットされます。
const (
zero = iota // 0
one = iota // 1
)
const (
two = iota // 0
three = iota // 1
)
また、constの中であれば、式のなかで利用することもできます。
const (
zero = iota * iota // 0
one // 1
two // 4
three // 9
)
const (
zero = iota != 1 // true
one // false
two // true
three // true
)
他の定義と混在しても、ConstSpecのたびにインクリメントしています。
const (
zero = "zero" // zero
one = iota // 1
two = "弐" // 弐
three = iota // 3
)
また、const内で先にiotaを設定すると結構面白かったです。iotaの機能ではなく、定数が優先されました。
const (
iota = "iota" // iota
zero = iota // iota
one // iota
two // iota
three // iota
)
型なしの整数なのでconstで使用した定数をTypeOfするとintになります。
package main
import (
"fmt"
"reflect"
)
const (
zero = iota
)
func main() {
fmt.Printf("zero type:%v\n", reflect.TypeOf(zero))
}
ですので、このような定義をすると変換できないのでコンパイルエラーとなります。
const(
zero string = iota
)
.../main.go:6: cannot convert 0 to type string
Githubではこういう感じで使われてたよ
軽く見た感じ単純にフラグ的なものをconstするソースが殆どだったんですが、
type ByteSize float64
const (
_ = iota // ignore first value by assigning to blank identifier
KB ByteSize = 1 << (10 * iota)
MB
GB
TB
PB
EB
ZB
YB
)
https://github.com/golang/go/blob/964639cc338db650ccadeafb7424bc8ebb2c0f6c/doc/progs/eff_bytesize.go
このソースはシフト演算子でByteSize型の値作ってて面白かったです。
おわりに
というわけで、iota列挙子のご紹介でした。
ひらめき次第で楽しく使えそうなので、こういうとこで使うと便利、こういう感じで使ってるとこあった、などあったら教えていただけるとうれしいです。
参考文献
Iota · golang/go Wiki
https://github.com/golang/go/wiki/Iota
The Go Programming Language Specification - Iota
https://golang.org/ref/spec#Iota
Yosssi's blog - Go言語の識別子iotaについて
http://yosssi.hatenablog.com/entry/2014/01/27/000135
Big Sky:: Recent entries from same category
http://mattn.kaoriya.net/software/lang/go/20141208093852.htm