Historia pytania:
Stałe w Go są nieodłączną częścią języka. Dla grupowanych stałych z automatycznym numerowaniem używa się identyfikatora iota, wprowadzonego już w najwcześniejszych wersjach Go, aby uprościć deklarację logicznie powiązanych wartości.
Problem:
Wielu programistów popełnia błędy przy pracy z iota, błędnie rozumiejąc, jak i gdzie jest zwiększane oraz jak jest stosowane w złożonych wzorcach deklaracji. Prowadzi to do błędnych wartości nawet w prostych strukturach podobnych do enumów.
Rozwiązanie:
iota pozwala na deklarowanie sekwencyjnych stałych i wygodne zbieranie flag bitowych. Zaczyna się od zera w każdej nowej grupie stałych. Każdy nowy blok const lub nowy wiersz w bloku zwiększa wartość iota.
Przykład kodu:
// Przykład maski flag i enum z iota const ( _ = iota // pominięcie zera FlagRead // 1 FlagWrite // 2 FlagExecute // 3 ) const ( ( // flagi bitowe FlagA = 1 << iota // 1 << 0 = 1 FlagB // 1 << 1 = 2 FlagC // 1 << 2 = 4 ) )
Kluczowe cechy:
Czy iota może zwiększyć się poza blokiem const lub przy deklaracji stałej nie w grupie?
Nie, iota działa tylko w obrębie grupy const. Przy pojedynczej deklaracji zawsze wartość wynosi 0.
const A = iota // 0 const B = iota // 0 (nowy blok)
Co się stanie, jeśli w grupie nie wszystkie wartości używają iota?
Tylko te, które są wyraźnie określone – otrzymają nową wartość, pozostałe otrzymują wyrażenie poprzedniego wiersza.
const ( A = iota // 0 B // 1 C = 10 // 10 D // 10 (nie iota, a powtórzenie wyrażenia z C) )
Jak deklarować maski bitowe za pomocą iota?
Maski bitowe realizuje się za pomocą przesunięcia: 1 << iota.
const ( F1 = 1 << iota // 1 F2 // 2 F3 // 4 )
Inżynier deklaruje flagi bitowe w różnych grupach, sądząc, że iota będzie kontynuować licznik:
const ( FlagA = 1 << iota // 1 FlagB // 2 ) const ( FlagC = 1 << iota // 1 – a nie 3 jak oczekiwano! )
Zalety:
Wady:
Wszystkie powiązane stałe są łączone w jedną grupę:
const ( FlagA = 1 << iota FlagB FlagC )
Zalety:
Wady: