在Apple有关与C API进行交互的文档中,他们描述了将NS_ENUM带有标记的C样式枚举作为Swift枚举导入的方式。这是有道理的,并且由于Swift中的枚举很容易作为enum值类型提供,因此很容易看到如何创建我们自己的枚举。
NS_ENUM
enum
再往下,它说了关于NS_OPTIONS标记C样式的选项:
NS_OPTIONS
Swift还会导入标有NS_OPTIONS宏的选项。而选项的行为类似于进口枚举,选项还可以支持一些位操作,如&,|和~。在Objective- C中,您表示一个空的选项集,其常数为零(0)。在Swift中,用于nil表示没有任何选项。
&
|
~
0
nil
鉴于optionsSwift中没有值类型,我们如何创建要使用的C-Style选项变量?
options
几乎与Swift 2.0相同。OptionSetType重命名为OptionSet,并且按惯例将枚举写为小写。
struct MyOptions : OptionSet { let rawValue: Int static let firstOption = MyOptions(rawValue: 1 << 0) static let secondOption = MyOptions(rawValue: 1 << 1) static let thirdOption = MyOptions(rawValue: 1 << 2) }
noneSwift 3建议不要提供选项,而只是使用空数组文字:
none
let noOptions: MyOptions = []
其他用法:
let singleOption = MyOptions.firstOption let multipleOptions: MyOptions = [.firstOption, .secondOption] if multipleOptions.contains(.secondOption) { print("multipleOptions has SecondOption") } let allOptions = MyOptions(rawValue: 7) if allOptions.contains(.thirdOption) { print("allOptions has ThirdOption") }
在Swift 2.0中,协议扩展会处理大多数样板文件,这些样板文件现在已作为符合的结构导入OptionSetType。(RawOptionSetType自Swift 2 beta 2起已消失。)声明要简单得多:
OptionSetType
RawOptionSetType
struct MyOptions : OptionSetType { let rawValue: Int static let None = MyOptions(rawValue: 0) static let FirstOption = MyOptions(rawValue: 1 << 0) static let SecondOption = MyOptions(rawValue: 1 << 1) static let ThirdOption = MyOptions(rawValue: 1 << 2) }
现在我们可以使用基于集合的语义MyOptions:
MyOptions
let singleOption = MyOptions.FirstOption let multipleOptions: MyOptions = [.FirstOption, .SecondOption] if multipleOptions.contains(.SecondOption) { print("multipleOptions has SecondOption") } let allOptions = MyOptions(rawValue: 7) if allOptions.contains(.ThirdOption) { print("allOptions has ThirdOption") }
看着由夫特导入的(Objective- C的选项UIViewAutoresizing,例如),我们可以看到,选项被声明为struct符合协议RawOptionSetType,这反过来又符合 _RawOptionSetType,Equatable,RawRepresentable,BitwiseOperationsType,和NilLiteralConvertible。我们可以这样创建自己的:
UIViewAutoresizing
struct
_RawOptionSetType
Equatable
RawRepresentable
BitwiseOperationsType
NilLiteralConvertible
struct MyOptions : RawOptionSetType { typealias RawValue = UInt private var value: UInt = 0 init(_ value: UInt) { self.value = value } init(rawValue value: UInt) { self.value = value } init(nilLiteral: ()) { self.value = 0 } static var allZeros: MyOptions { return self(0) } static func fromMask(raw: UInt) -> MyOptions { return self(raw) } var rawValue: UInt { return self.value } static var None: MyOptions { return self(0) } static var FirstOption: MyOptions { return self(1 << 0) } static var SecondOption: MyOptions { return self(1 << 1) } static var ThirdOption: MyOptions { return self(1 << 2) } }
现在,我们可以像对待MyOptions苹果文档中所述的那样对待这个新的选项集:您可以使用enum-like语法:
let opt1 = MyOptions.FirstOption let opt2: MyOptions = .SecondOption let opt3 = MyOptions(4)
而且它的行为也像我们期望的选项那样:
let singleOption = MyOptions.FirstOption let multipleOptions: MyOptions = singleOption | .SecondOption if multipleOptions & .SecondOption != nil { // see note println("multipleOptions has SecondOption") } let allOptions = MyOptions.fromMask(7) // aka .fromMask(0b111) if allOptions & .ThirdOption != nil { println("allOptions has ThirdOption") }
我已经构建了一个生成器来创建Swift选项集,而无需进行所有查找/替换。
最新: 对Swift 1.1 beta 3的修改。