Raw value for enum case must be a literal

后端 未结 4 1135
花落未央
花落未央 2021-02-06 22:38

I have this enum:

enum GestureDirection:UInt {
    case Up =       1 << 0
    case Down =     1 << 1
    case Left =     1 << 2
    case Right          


        
相关标签:
4条回答
  • 2021-02-06 23:04

    That's because 1 << 0 isn't a literal. You can use a binary literal which is a literal and is allowed there:

    enum GestureDirection:UInt {
        case Up =       0b000
        case Down =     0b001
        case Left =     0b010
        case Right =    0b100
    }
    

    Enums only support raw-value-literals which are either numeric-literal (numbers) string-literal­ (strings) or boolean-literal­ (bool) per the language grammar.

    Instead as a workaround and still give a good indication of what you're doing.

    0 讨论(0)
  • 2021-02-06 23:09

    You seems to want a bitwise support for your enums, but if you regards a translation of NS_OPTIONS Objective-C in Swift, that's not represented by a Swift Enum but a struct inherit from RawOptionSetType.

    If you need example or instructions, you can look at this NSHipster article

    That's could be done with something like this :

    struct UIViewAutoresizing : RawOptionSetType {
        init(_ value: UInt)
        var value: UInt
        static var None: UIViewAutoresizing { get }
        static var FlexibleLeftMargin: UIViewAutoresizing { get }
        static var FlexibleWidth: UIViewAutoresizing { get }
        static var FlexibleRightMargin: UIViewAutoresizing { get }
        static var FlexibleTopMargin: UIViewAutoresizing { get }
        static var FlexibleHeight: UIViewAutoresizing { get }
        static var FlexibleBottomMargin: UIViewAutoresizing { get }
    }
    

    Regards,

    0 讨论(0)
  • 2021-02-06 23:18

    For attributes which are not mutually exclusive I would also recommend to use a struct based on RawOptionSetType as @Vincent suggested. One advantage is that you get all bit operations for free.

    Here is a full working example:

    struct GestureDirection : RawOptionSetType {
        let rawValue : UInt8
        init(rawValue: UInt8) {
            self.rawValue = rawValue
        }
    
        init(nilLiteral: ()) {
            self.rawValue = 0
        }
        static var allZeros: GestureDirection { return self(rawValue: 0) }
    
        static var Top:   GestureDirection { return self(rawValue: 1 << 0) }
        static var Down:  GestureDirection { return self(rawValue: 1 << 1) }
        static var Left:  GestureDirection { return self(rawValue: 1 << 2) }
        static var Right: GestureDirection { return self(rawValue: 1 << 3) }
    }
    

    Usage:

    // Initialize:
    var direction : GestureDirection = .Top | .Right
    
    // Test:
    if (direction & .Top) != nil {
       // ...
    }
    
    // Add an option:
    direction |= .Left
    
    // Remove an option:
    direction &= ~(.Right)
    

    Update for Swift 2: As of Swift 2, this can be simpler done with the new OptionSetType protocol, which offers a set-like interface (see also the recently added answers to How to create NS_OPTIONS-style bitmask enumerations in Swift?).

    We just have to define the underlying storage type and the pre-defined values:

    struct GestureDirection : OptionSetType {
        let rawValue : UInt8
    
        static let Top   = GestureDirection(rawValue: 1 << 0)
        static let Down  = GestureDirection(rawValue: 1 << 1)
        static let Left  = GestureDirection(rawValue: 1 << 2)
        static let Right = GestureDirection(rawValue: 1 << 3)
    }
    

    Usage:

    // Initialize:
    var direction : GestureDirection = [ .Top, .Right ]
    
    // Test:
    if direction.contains(.Top) {
        // ...
    }
    
    // Add an option:
    direction.insert(.Left)
    
    // Remove an option:
    direction.remove(.Right)
    
    0 讨论(0)
  • 2021-02-06 23:24

    Swift 2.2 Version : In my case I needed to Convert the String Enum Values to be used in Localisable Strings. So added this method inside my enum.

        enum DisplayCellTitle: String {
        case Clear 
    
        func labelTitle() -> String {
            switch self {
            case .Clear:
                return "LBL_CLEAR".localizedWithComment("Clear")
            }
        }
    }
    

    And then Use it like so :

            // Get the localised value of the Cell Label Title
        let lblTitle = DisplayCellTitle.labelTitle(cellTitle)()
    

    where cellTitle passed in is just one of these CellTitle Enum Values

    0 讨论(0)
提交回复
热议问题