はじめに
自動的に0から連番を振ってもらえる整数の列挙型に限定した内容です。
- Xcode 6.1.1 + Playground
CやObjCでは以下のような感じで最後に適当な要素を用意してカウントするのが定石だと思いますが、
Objective-C
// 名前はいい加減です。
typedef enum {
A = 0
B,
C,
count, // カウンタ
} Test;
Swiftの列挙型で同様の事を実現する方法を考えてみました。
案1
以下のような方法が簡単でしょうか。
Swift
import UIKit
enum Test: Int {
case A
case B
case C
case _count // ダミーカウンタ
static let count = _count.rawValue // 利用するものはこちら
}
println(Test.count) // 3
これなら利用時にわざわざrawValueやコンバージョンを利用しなくてもInt型として要素数が利用できるかなと。
特に、次のような、要素の型がInt型以外の場合に効果が有るのではないかと思います。
Swift
import UIKit
enum Test: UInt8 {
case A
case B
case C
case _count // ダミーカウンタ
static let count = Int(_count.rawValue) // Int型へコンバージョン
}
// こういった引数にInt型を要求されるような場所で可読性が上がる気がします。
let array = [Hoge](count: Test.count, repeatedValue: Hoge())
案2
tottokotkd様よりコメントを頂きまして、それをヒントに自分なりにいじってみました。
import UIKit
/// 列挙体の要素数をカウントします。
func countEnumElements(test: (Int) -> Any?) -> Int {
var i = 0
while test(i) != nil {
i++
}
return i
}
enum TestInt: Int {
case A
case B
case C
case D
static let count = countEnumElements({TestInt(rawValue: $0)})
}
enum TestUInt8: UInt8 {
case A
case B
case C
static let count = countEnumElements({TestUInt8(rawValue: UInt8($0))})
}
println(TestInt.count) // 4
println(TestUInt8.count) // 3
こちらの方はダミーカウンタ(_count)が不要なので、少しスッキリするかもしれません。
ただ、初回実行時にカウント処理が1回は走りますので、膨大な要素数が存在する場合は案1の方が高速かと予想されます。
終わりに
もっと良い方法があれば教えて下さい。