首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Swift中创建NS_OPTIONS样式的位掩码枚举?

如何在Swift中创建NS_OPTIONS样式的位掩码枚举?
EN

Stack Overflow用户
提问于 2014-06-06 01:09:54
回答 15查看 43.6K关注 0票数 140

在苹果关于与C-marked交互的文档中,它们描述了将NS_ENUM APIs样式枚举导入为Swift枚举的方式。这是有道理的,而且由于Swift中的枚举很容易作为enum值类型提供,因此很容易看到如何创建我们自己的枚举。

再往下看,关于NS_OPTIONS-marked C风格的选项是这样的:

Swift还导入用NS_OPTIONS宏标记的选项。虽然选项的行为类似于导入的枚举,但选项还可以支持一些按位操作,如&|~。在Objective-C中,您使用常量零(0)表示一个空的期权集。在Swift中,使用nil表示缺少任何选项。

假设Swift中没有options值类型,我们如何创建一个C风格的options变量来使用呢?

EN

回答 15

Stack Overflow用户

回答已采纳

发布于 2014-06-06 01:09:54

Swift 3.0

几乎与Swift 2.0完全相同。OptionSetType被重命名为OptionSet,按照约定,枚举是小写的。

代码语言:javascript
复制
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)
}

Swift 3的建议是简单地使用空数组文字,而不是提供none选项:

代码语言:javascript
复制
let noOptions: MyOptions = []

其他用法:

代码语言:javascript
复制
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

在SWIFT2.0中,协议扩展负责处理这些模板的大部分内容,这些模板现在作为符合OptionSetType的结构导入。(RawOptionSetType在Swift 2 beta 2中消失了。)声明要简单得多:

代码语言:javascript
复制
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中使用基于集合的语义了

代码语言:javascript
复制
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 1.2

查看Swift导入的Objective-C选项(例如,UIViewAutoresizing),我们可以看到选项被声明为符合协议RawOptionSetTypestruct,该协议又符合_RawOptionSetTypeEquatableRawRepresentableBitwiseOperationsTypeNilLiteralConvertible。我们可以像这样创建我们自己的:

代码语言:javascript
复制
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语法:

代码语言:javascript
复制
let opt1 = MyOptions.FirstOption
let opt2: MyOptions = .SecondOption
let opt3 = MyOptions(4)

它的行为也像我们所期望的选项的行为:

代码语言:javascript
复制
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")
}

我已经构建了一个没有所有查找/替换的generator to create a Swift option set

最新版本:针对Swift 1.1测试版3的修改。

票数 265
EN

Stack Overflow用户

发布于 2014-10-01 05:14:05

Xcode6.1Beta2给RawOptionSetType协议带来了一些变化(参见这个Airspeedvelocity blog entryApple release notes)。

基于Nate Cooks的例子,这里是一个更新的解决方案。您可以像这样定义自己的选项集:

代码语言:javascript
复制
struct MyOptions : RawOptionSetType, BooleanType {
    private var value: UInt
    init(_ rawValue: UInt) { self.value = rawValue }

    // MARK: _RawOptionSetType
    init(rawValue: UInt) { self.value = rawValue }

    // MARK: NilLiteralConvertible
    init(nilLiteral: ()) { self.value = 0}

    // MARK: RawRepresentable
    var rawValue: UInt { return self.value }

    // MARK: BooleanType
    var boolValue: Bool { return self.value != 0 }

    // MARK: BitwiseOperationsType
    static var allZeros: MyOptions { return self(0) }

    // MARK: User defined bit values
    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) }
    static var All: MyOptions           { return self(0b111) }
}

然后可以像这样使用它来定义变量:

代码语言:javascript
复制
let opt1 = MyOptions.FirstOption
let opt2:MyOptions = .SecondOption
let opt3 = MyOptions(4)

像这样测试bits:

代码语言:javascript
复制
let singleOption = MyOptions.FirstOption
let multipleOptions: MyOptions = singleOption | .SecondOption
if multipleOptions & .SecondOption {
    println("multipleOptions has SecondOption")
}

let allOptions = MyOptions.All
if allOptions & .ThirdOption {
    println("allOptions has ThirdOption")
}
票数 12
EN

Stack Overflow用户

发布于 2015-06-28 19:01:23

文档中的Swift 2.0示例:

代码语言:javascript
复制
struct PackagingOptions : OptionSetType {
    let rawValue: Int
    init(rawValue: Int) { self.rawValue = rawValue }

    static let Box = PackagingOptions(rawValue: 1)
    static let Carton = PackagingOptions(rawValue: 2)
    static let Bag = PackagingOptions(rawValue: 4)
    static let Satchel = PackagingOptions(rawValue: 8)
    static let BoxOrBag: PackagingOptions = [Box, Bag]
    static let BoxOrCartonOrBag: PackagingOptions = [Box, Carton, Bag]
}

你可以在here上找到它

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24066170

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档