Исходное значение для случая перечисления должно быть буквальным
У меня есть это перечисление:
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
Это потому, что 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