自分は iota の使い所が分からなかった。
なんか事故りそうだし、明示的に値を宣言した方が分かりやすいような気がする。
で、こんなツイートをしたら・・・
#golang の iota 使った定数定義って、定数の並び順によって値が変わるから、なんか事故りやすい印象あるんだよな。誤って順番変えちゃいました的な。みんな使ってるのかな。iota 使わなくても設定する値を間違えたら結局事故るから、あまり気にしなくてもいーのかな。
— pospome (@pospome) 2017年8月19日
tenntenn さんと kaneshin0120 さんに返信をいただいた。
DBに保存するような値は基本使ってないですね
— tenntennʕ ◔ϖ◔ʔ ==Go (@tenntenn) 2017年8月19日
なるほど。理由としては「永続化される値だと事故るとデータの修正が発生して面倒」だからでしょうか? 個人的に永続化される、されないに関わらず、iota 使うメリットがいまいち分からないんですよね。
— pospome (@pospome) 2017年8月20日
iotaは「数値に意味がある」定数には使用しないという点でC言語の列挙型と同じ扱いです。数値に意味がない定数には是非使うと良いです。例えばビット演算のフラグとして扱う場面とか(https://t.co/P8UhudEd8J)
— kaneshin (@kaneshin0120) 2017年8月20日
DBの値は定義してあるという点で、数値に意味のある値になります!
— kaneshin (@kaneshin0120) 2017年8月20日
ですねー
— tenntennʕ ◔ϖ◔ʔ ==Go (@tenntenn) 2017年8月20日
なるほどー!ありがとうございます。今までモヤモヤしてたのですが、スッキリしました。
— pospome (@pospome) 2017年8月20日
ということで、golang の標準ライブラリを grep してみた。
以下は皆大好き net/http package の iota。
const ( // StateNew represents a new connection that is expected to // send a request immediately. Connections begin at this // state and then transition to either StateActive or // StateClosed. StateNew ConnState = iota // StateActive represents a connection that has read 1 or more // bytes of a request. The Server.ConnState hook for // StateActive fires before the request has entered a handler // and doesn't fire again until the request has been // handled. After the request is handled, the state // transitions to StateClosed, StateHijacked, or StateIdle. // For HTTP/2, StateActive fires on the transition from zero // to one active request, and only transitions away once all // active requests are complete. That means that ConnState // can not be used to do per-request work; ConnState only notes // the overall state of the connection. StateActive // StateIdle represents a connection that has finished // handling a request and is in the keep-alive state, waiting // for a new request. Connections transition from StateIdle // to either StateActive or StateClosed. StateIdle // StateHijacked represents a hijacked connection. // This is a terminal state. It does not transition to StateClosed. StateHijacked // StateClosed represents a closed connection. // This is a terminal state. Hijacked connections do not // transition to StateClosed. StateClosed )
以下は皆大好き?? time package の iota
const ( January Month = 1 + iota February March April May June July August September October November December )
golang 内での定数は他の定数と識別できればよく、
その値自体にあまり意味はないので、
ちょこちょこ iota が利用されている。
kaneshin さんが仰っている「DBの値には意味がある」というのは、
その定数が golang のコード上の定義ではなく、
DB側で定義されている値なので、
iota で実装すべきではないってことだと解釈している。
golang に実装する定数はDB側で定義されている値に合わせるべきなので、
明示的に設定しましょうねって感じかな。
iota を使うと定数の定義順を間違えると値が変わって事故るってのは変わらないけど、
iota を使わなくても設定する値を間違えれば事故るから、
そこはあまり考えなくていーのかもしれない。
iota は定義する順番さえ守っていれば事故らない。