【问题标题】:Raw value for enum case must be a literal枚举大小写的原始值必须是文字
【发布时间】:2015-05-19 12:01:43
【问题描述】:

我有这个枚举:

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

但在每种情况下我都会出错:

枚举大小写的原始值必须是文字

我不明白。

Swift 1.2、Xcode 6.3.2

【问题讨论】:

  • 如果这些情况是互斥的,那么为什么要分配值 1、2、4、8?如果它们不是互斥的,那么您不应该使用enum 来表示它们。
  • @MartinR 我希望能够做方向 = .Left | . 对,但我刚刚测试过,但没有用 x) 我应该使用什么而不是枚举?

标签: ios swift


【解决方案1】:

那是因为1 &lt;&lt; 0 不是文字。您可以使用二进制文字,它是文字并且允许存在:

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

枚举仅支持raw-value-literals,它们可以是numeric-literal(数字)string-literal­(字符串)或boolean-literal­(布尔)每个language grammar

作为一种解决方法,仍然可以很好地表明您正在做什么。

【讨论】:

  • 我明白了,所以 Swift 中的枚举不支持位运算符?
  • 不支持任何操作。它仅支持文字。 (1 + 5) 也不行
  • @Arbitur 不,但这很容易做到,因为枚举很容易转换为原始值,然后您可以或反馈给枚举。
  • @BenjaminGruenbaum:但是您不能将原始值 5(向上+向左)转换回枚举。
  • @MartinR 当然你可以GestureDirection(rawValue: (GestureDirection.Up.rawValue | GestureDirection.Left.rawValue) 但它当然必须是一个存在的方向 - 在这种情况下,UpLeft 没有任何值,并且必须为此添加这些值用法(如果您希望它是枚举类型)当然。更新:没关系 - 我想这就是你所说的。
【解决方案2】:

(针对 Swift 5 及更高版本更新了答案。旧 Swift 版本的解决方案可在编辑历史记录中找到。)

对于不互斥的属性,您可以使用struct 并声明符合OptionSet 协议。优点是您可以免费获得所有位操作。

您只需定义底层存储类型和预定义值:

struct GestureDirection : OptionSet {
    let rawValue : UInt8

    static let top   = Self(rawValue: 1 << 0)
    static let down  = Self(rawValue: 1 << 1)
    static let left  = Self(rawValue: 1 << 2)
    static let right = Self(rawValue: 1 << 3)
}

用法:

// Initialize:
var direction : GestureDirection = [ .top, .right ]

// Test:
if direction.contains(.top) {
    // ...
}

// Add an option:
direction.insert(.left)

// Remove an option:
direction.remove(.right)

【讨论】:

  • 这会启用let dir1 = .Right | .Left; let dir2 = .Left; if dir1 == dir2 {//dir2 allowed}吗?
  • @Arbitur:“允许 dir2”到底是什么意思? dir1 == dir2 如果它们相等,则为真。也许你的意思是if (dir1 &amp; dir2) != nil
  • 是的,一定是这样。我希望 dir1 成为允许的方向,然后检查 dir2 是否是允许的方向
  • @Arbitur: if (dir1 &amp;&amp; dir2) == dir2 将测试 dir2 是否仅包含在 dir1 中设置的方向。 – 如果您经常需要,可以定义一个运算符或方法。
  • 这是一个可靠的解决方案,并为您提供与编辑中提到的枚举相同的便捷语法。 +1
【解决方案3】:

Swift 2.2 版本: 在我的情况下,我需要转换要在可本地化字符串中使用的字符串枚举值。所以在我的枚举中添加了这个方法。

    enum DisplayCellTitle: String {
    case Clear 

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

然后像这样使用它:

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

其中传入的 cellTitle 只是这些 CellTitle 枚举值之一

【讨论】:

    【解决方案4】:

    您似乎希望为您的枚举提供按位支持,但如果您考虑在 Swift 中对 NS_OPTIONS Objective-C 的翻译,则它不是由 Swift Enum 表示,而是由 struct 继承自 RawOptionSetType

    如果您需要示例或说明,可以查看此NSHipster article

    这可以通过这样的方式来完成:

    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 }
    }
    

    问候,

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-04
      • 1970-01-01
      相关资源
      最近更新 更多