1. curepine

    No comment

    curepine
Changes in body
Source | HTML | Preview
@@ -1,195 +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)の内での既定された識別子です。
型なしの整数の連番を生成します。具体例を見ましょう。
```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
)
```
他の定義と混在しても、ConstSpecのたびにインクリメントしています。
```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型の値作ってて面白かったです。
+このソースはビット演算で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