コンテンツにスキップ

Go/iota

出典: フリー教科書『ウィキブックス(Wikibooks)』
< Go

Goにおける iota は、const 宣言ブロック内でのみ使用できる事前宣言された識別子です。これは、連続する整数値を生成するために設計されており、列挙型 (enum) のような定数を定義する際に非常に便利です。

基本的な振る舞い:

[編集]
  • const キーワードが現れるたびに 0 にリセットされます。
  • const 宣言ブロック内で、各定数仕様 (各行) の後に自動的に 1 ずつインクリメントされます。

他のキーワードや事前宣言された識別子との組み合わせ:

[編集]
  1. const: iota は常に const 宣言ブロック内で使用されます。const ブロックの開始時に 0 にリセットされるため、複数の const ブロック内で独立した連番を生成できます。
        const (
            A = iota // A == 0
            B        // B == 1
            C        // C == 2
        )
    
        const (
            X = iota // X == 0 (新しい const ブロックでリセット)
            Y        // Y == 1
        )
    
  2. ブランク識別子 (): 特定の値をスキップしたい場合や、最初の値を無視したい場合に と組み合わせて使用します。
        const (
            _ = iota // 0 (無視)
            KB = 1 << (10 * iota) // 1 << (10 * 1)
            MB                      // 1 << (10 * 2)
            GB                      // 1 << (10 * 3)
        )
    
  3. ビットシフト演算子 (<<): ビットフラグやサイズの定義など、2のべき乗を連続して生成する際に便利です。
        const (
            FlagA = 1 << iota // 1 << 0 == 1
            FlagB             // 1 << 1 == 2
            FlagC             // 1 << 2 == 4
        )
    
  4. 算術演算子 (+, -, *, / など): iota を算術式の中で使用して、より複雑な連続値を生成できます。
        const (
            One = iota + 1 // 0 + 1 == 1
            Two            // 1 + 1 == 2
            Three          // 2 + 1 == 3
        )
    
  5. 型指定: iota は型のない定数として扱われますが、明示的に型を指定することも可能です。
        type Weekday int
    
        const (
            Sunday Weekday = iota // Sunday == 0 (Weekday 型)
            Monday                // Monday == 1
            Tuesday               // Tuesday == 2
            // ...
        )
    
  6. 関数: iota を関数の引数として直接渡すことはできませんが、const ブロック内で関数呼び出しと組み合わせて使用することは可能です。ただし、const の評価時に実行可能な関数である必要があります。
        func powerOfTwo(n int) int {
            return 1 << n
        }
    
        const (
            P2_0 = powerOfTwo(iota) // powerOfTwo(0) == 1
            P2_1                    // powerOfTwo(1) == 2
            P2_2                    // powerOfTwo(2) == 4
        )
    

ユースケース:

[編集]
  1. 列挙型 (Enum) の定義: 最も一般的なユースケースです。関連する定数に連続した整数値を自動的に割り当てることで、コードの可読性と保守性を向上させます。
        type Status int
    
        const (
            Open Status = iota
            Pending
            Closed
            Cancelled
        )
    
        func main() {
            var currentStatus Status = Pending
            println(currentStatus) // Output: 1
        }
    
  2. ビットフラグの定義: 各ビットが特定の状態を表すビットマスクを簡潔に定義できます。
        const (
            Readable = 1 << iota // 1
            Writable             // 2
            Executable           // 4
        )
    
        func main() {
            permissions := Readable | Writable
            println(permissions) // Output: 3
        }
    
  3. サイズの定義: キロバイト、メガバイトなどのサイズ単位を定義する際に、2のべき乗を簡単に生成できます。
        type ByteSize float64
    
        const (
            _ = iota // ignore first value by assigning to blank identifier
            KB ByteSize = 1 << (10 * iota)
            MB
            GB
            TB
        )
    
        func main() {
            println(MB) // Output: 1.048576e+06
        }
    
  4. 連続するエラーコードの定義: エラーの種類に応じて連続したエラーコードを定義する際に便利です。
        const (
            ErrInvalidInput = iota + 100
            ErrNotFound
            ErrPermissionDenied
        )
    
        func main() {
            println(ErrNotFound) // Output: 101
        }
    
  5. 状態遷移の定義: 状態機械における状態を連続した整数値で表現できます。
        type State int
    
        const (
            StateInitial State = iota
            StateProcessing
            StateCompleted
            StateError
        )
    
        func main() {
            var currentState State = StateProcessing
            println(currentState) // Output: 1
        }
    

iota 使用時の注意点:

[編集]
  • iotaconst 宣言ブロック内でのみ有効です。
  • const ブロック内で宣言された各定数仕様 (行) ごとにインクリメントされます。複数の定数を同じ行で宣言しても、iota は一度しかインクリメントされません。
        const (
            A, B = iota, iota // A == 0, B == 0 (iota は一度だけインクリメント)
            C, D              // C == 1, D == 1
        )
    
  • iota の値はコンパイル時に決定される定数です。実行時に変更することはできません。
  • iota を使用すると、定数の順序に依存したコードになりやすいため、定数の順序を変更する際には注意が必要です。

iota は、Go言語で列挙型や関連する定数を簡潔かつ効率的に定義するための強力なツールです。その振る舞いを理解し、適切なユースケースで使用することで、より可読性が高く、保守しやすいコードを書くことができます。