Подтвердить что ты не робот

Исходное значение для случая перечисления должно быть буквальным

У меня есть это перечисление:

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

4b9b3361

Ответ 1

Это потому, что 1 << 0 не является литералом. Вы можете использовать бинарный литерал, который является литералом и разрешен там:

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

Только перечисления поддерживают raw-value-literal, которые либо numeric-literal (числа) string-literal­ (строки), либо boolean-literal­ (bool) в грамматике .

Вместо этого в качестве обходного пути и по-прежнему хорошо показывайте, что вы делаете.

Ответ 2

Для атрибутов, которые не являются взаимоисключающими, я также рекомендовал бы используйте struct на основе RawOptionSetType, как предположил @Vincent. Одно из преимуществ заключается в том, что вы получаете все бит операции бесплатно.

Вот полный рабочий пример:

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

Использование:

// Initialize:
var direction : GestureDirection = .Top | .Right

// Test:
if (direction & .Top) != nil {
   // ...
}

// Add an option:
direction |= .Left

// Remove an option:
direction &= ~(.Right)

Обновление для Swift 2: С Swift 2 это проще сделать с новым протоколом OptionSetType, который предлагает набор интерфейс (см. также недавно добавленные ответы на Как создать NSM файлы в стиле Swift?.

Нам просто нужно определить базовый тип хранилища и предопределенные значения:

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

Использование:

// Initialize:
var direction : GestureDirection = [ .Top, .Right ]

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

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

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

Ответ 3

Кажется, вам нужна побитовая поддержка для ваших перечислений, но если вы считаете перевод NS_OPTIONS Objective-C в Swift, который не представлен Swift Enum, а struct наследует от RawOptionSetType.

Если вам нужен пример или инструкции, вы можете посмотреть статью NSHipster

Это можно сделать примерно так:

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

Привет,

Ответ 4

Swift 2.2 Версия: В моем случае мне нужно было преобразовать значения перечисления строк, которые будут использоваться в Localisable Strings. Поэтому добавлен этот метод внутри моего перечисления.

    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