2014-10-08 69 views
14

我試圖隨機選擇一個枚舉值,這是我當前的嘗試:斯威夫特:選擇了一個隨機枚舉值

enum GeometryClassification { 

    case Circle 
    case Square 
    case Triangle 
    case GeometryClassificationMax 

} 

和隨機選擇:

let shapeGeometry = (arc4random() % GeometryClassification.GeometryClassificationMax) as GeometryClassification 

這不過失敗草草收場。

我得到這樣的錯誤:

'GeometryClassification' is not convertible to 'UInt32' 

如何解決,任何想法?

回答

22

我不是瘋了你最後的情況下,有 - 好像你包括.GeometryClassificationMax只是爲了使隨機選擇。在使用switch聲明的任何地方,您都需要考慮額外的情況,並且它沒有語義值。相反,在enum上的靜態方法可以確定最大值並返回一個隨機的情況,並且會更容易理解和維護。

enum GeometryClassification: UInt32 { 
    case Circle 
    case Square 
    case Triangle 

    private static let _count: GeometryClassification.RawValue = { 
     // find the maximum enum value 
     var maxValue: UInt32 = 0 
     while let _ = GeometryClassification(rawValue: maxValue) { 
      maxValue += 1 
     } 
     return maxValue 
    }() 

    static func randomGeometry() -> GeometryClassification { 
     // pick and return a new value 
     let rand = arc4random_uniform(_count) 
     return GeometryClassification(rawValue: rand)! 
    } 
} 

,現在您可以在switch聲明排出enum

switch GeometryClassification.randomGeometry() { 
case .Circle: 
    println("Circle") 
case .Square: 
    println("Square") 
case .Triangle: 
    println("Triangle") 
} 
+3

你是對的 - 我最終用這種方法使它更具可讀性。感謝你的努力。 – 2014-10-08 16:53:59

+0

'++ maxValue'將在Swift 3中被棄用。你將如何去修復你的代碼? – Cesare 2016-06-02 18:32:09

+0

@Cesare:你可以在'while循環內移動增量。 – 2016-06-02 19:13:10

5

您需要爲您的枚舉指定一個原始類型。如果使用的是整數類型,則枚舉的情況下的值將是自動生成的從0開始:

enum GeometryClassification: UInt32 { 
    case Circle 
    case Square 
    case Triangle 
    case GeometryClassificationMax 
} 

「不像C和Objective-C,在創建時夫特枚舉成員沒有被分配一個默認的整數值「。 - 根據this頁面。指定整數類型讓它知道以通常的方式生成值。

然後你就可以產生這樣的隨機值:

let randomEnum: GeometryClassification = GeometryClassification.fromRaw(arc4random_uniform(GeometryClassification.GeometryClassificationMax.toRaw()))! 

這是一個可怕的醜陋的電話,以及所有那些「fromRaw」和'toRaw的叫聲是相當不雅,所以我真的建議產生隨機UInt32的你想先,然後創建從價值GeometryClassification是在範圍:

GeometryClassification.fromRaw(someRandomUInt32) 
+0

在這種情況下,您不需要指定特定值;他們將從'0'開始自動生成。你從docs中引用的部分只有在'enum'不具有基於整數的原始類型時纔是。進一步在同一個文檔中:「當整數用於原始值時,如果某些枚舉成員沒有指定值,它們會自動遞增。」 – 2014-10-08 15:56:25

+0

同樣的錯誤仍然令人遺憾:/ – 2014-10-08 15:56:32

+0

@SebastianFlückiger您需要從arc4random返回的原始值創建'GeometryClassification':'let shapeGeometry = GeometryClassification(rawValue:(arc4random()%GeometryClassification.GeometryClassificationMax.rawValue)) ' – 2014-10-08 15:58:36

7

既然你是枚舉類中,具有隨機的()方法中引用的最高值明確將消除不必每次都數得過來:

enum GeometryClassification: UInt32 { 
    case Circle 
    case Square 
    case Triangle 

    static func random() -> GeometryClassification { 
     // Update as new enumerations are added 
     let maxValue = Triangle.rawValue 

     let rand = arc4random_uniform(maxValue+1) 
     return GeometryClassification(rawValue: rand)! 
    } 
} 
+0

這不適用於Swift 1.2。它想要一個rawValue分配給枚舉。反過來,這意味着它只適用於具有Int rawValue類型的枚舉。 – BadmintonCat 2015-05-14 06:46:42

+0

我在我的代碼上有一個錯字,正在返回錯誤的類型。 – stevex 2015-05-14 10:36:29

1

這裏是我的雨燕1.2的見解:

enum GeometryClassification : Int { 
    case Circle = 0 
    case Square = 1 
    case Triangle = 2 

    static func random() -> GeometryClassification { 
     let min = MutationType.Circle.rawValue 
     let max = MutationType.Triangle.rawValue 
     let rand = Int.random(min: min, max: max) // Uses ExSwift! 
     return self(rawValue: rand)! 
    } 
}