1. curepine

    Posted

    curepine
Changes in title
+iotaの紹介
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,195 @@
+[Go AdventCalendar2016](http://qiita.com/advent-calendar/2016/go)の9日目(2016/12/09)の記事です。
+前の記事は massa142さんの「[Hacker Newsを一覧表示してくれるCLIツールを書いた]」(http://qiita.com/massa142/items/df181fc77a4d67e0f2a4)でした。
+
+# はじめに
+ちょっとマイナーなGolangの言語仕様である、iotaについて紹介します。
+結構入門書とかにも書いてあるんですが、読み飛ばしがちなんですよね。
+特に新規性がある内容ではないので、タイトルでもう知ってるわ!という方はそっ閉じしてもらって大丈夫です。
+
+
+# iotaとは
+iotaは、定数宣言(const)の内での既定された識別子です。
+const内で作用し、型なしの整数の連番を生成します。具体例を見ましょう。
+
+```go
+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", two)
+}
+
+```
+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", two)
+}
+
+```
+https://play.golang.org/p/IFkQnrwujr
+
+ConstSpec毎にインクリメントされ、次の予約語constが現れたらリセットされます。
+
+```go
+const (
+ zero = iota // 0
+ one = iota // 1
+)
+const (
+ two = iota // 0
+ three = iota // 1
+)
+```
+
+
+また、constの中であれば、式のなかで利用することもできます。
+
+```go
+const (
+ zero = iota * iota // 0
+ one // 1
+ two // 4
+ three // 9
+)
+```
+
+```go
+const (
+ zero = iota != 1 // true
+ one // false
+ two // true
+ three //false
+)
+```
+
+
+他の定義と混在する場合は、その関数が設定されている位置に応じてiotaの結果が帰ってくるようです。
+
+```go
+const (
+ zero = "zero" // zero
+ one = iota // 1
+ two = "弐" // 弐
+ three = iota // 3
+)
+```
+
+また、const内で先にiotaを設定すると結構面白かったです。iotaの機能ではなく、定数が優先されました。
+
+```go
+const (
+ iota = "iota" // iota
+ zero = iota // iota
+ one // iota
+ two // iota
+ three // iota
+)
+```
+
+型なしの整数なのでconstで使用した定数をTypeOfするとintになります。
+
+```go
+package main
+
+import (
+ "fmt"
+ "reflect"
+)
+
+const (
+ zero = iota
+)
+
+func main() {
+ fmt.Printf("zero type:%v\n", reflect.TypeOf(zero))
+}
+```
+https://play.golang.org/p/851VyBBlgs
+
+ですので、このような定義をするとコンパイルエラーとなります。
+
+```go
+const(
+ zero string = iota
+)
+```
+>.../main.go:6: cannot convert 0 to type string
+
+
+# Githubではこういう感じで使われてたよ
+
+軽く見た感じ単純にフラグ的なものをconstするソースが殆どだったんですが、
+
+
+```go
+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