Swift里的位集

背景

大家在OC中写过枚举,Foundation框架为我们提供了统一、便捷的枚举定义方法,所以举个例子可以有如下方式:

  • 我们可以如下定义一些相互之间独立,不会组合的一些普通枚举,例如
typedef NS_ENUM(NSUInteger, WEATHER) {
         WEATHERRain = 0,
         WEATHERSnow,
         WEATHERWind
};
  • 此外OC还有第二种统一的枚举定义方式:NS_OPTIONS,这种方式可以用来表示多个枚举值之间可以组合的枚举,可以理解为每个枚举值是一个选项,变量可以同时选择多个选项,通常使用移位来定义,如表示swift和OC:
typedef NS_OPTIONS(NSUInteger, LANGUAGESTATE) {
       LANGUAGESTATENone = 0,
       LANGUAGESTATESwift = 1 << 0,
       LANGUAGESTATEOC = 1 << 1,
};

这样定义枚举的话 ,我们可以使用或运算来表示组合的情况,例如:

LANGUAGESTATE state= LANGUAGESTATESwift | LANGUAGESTATEOC;

如果想判断某个枚举变量对应位的状态,可以用“与”运算得到对应位置的值

BOOL isSwift = state & LANGUAGESTATESwift;

至于Swift里呢大家也经常写枚举:

enum Response {                                    
     case ok
     case error(Int)
}

那么大家Swift里有没有写过类似OC的位枚举呢?今天就是要和大家分享一下这个知识

Swift里如何定义与使用

Swift里用OptionSet来表示这个类型,是向位集提供数学集接口的一种类型(读完下面的内容你再回头看一下这句话,就觉得很精炼了)。
为什么要用这个呢?在自定义类型中采用此协议,可以对这些类型执行与集合相关的操作,例如成员资格测试、并集和交集。更重要的是,当使用特定标准实施时,采用该协议不需要我们做额外的工作。

定义OptionSet

创建选项集时,请在类型声明中包含rawValue属性。要使我们的类型自动具有集合相关的操作的默认实现,rawValue属性的类型必须符合FixedWidthInteger协议,例如Int或UInt8。接下来,创建唯一选项作为自定义类型的静态属性,为每个属性的原始值使用2的唯一幂(1、2、4、8、16等),这样每个属性都可以由类型的原始值的一位表示。

struct WeaponOptions: OptionSet {
        let rawValue: Int
        
        static let sword = WeaponOptions(rawValue: 0 << 1)
        static let spear = WeaponOptions(rawValue: 1 << 1)
        static let all: WeaponOptions = [sword, spear]
    }

这里有3个要注意的事情

  1. rawValue属性的类型必须符合FixedWidthInteger协议,比如 你不能拿String来用。
  2. rawValue这个行是Set定义他自己的原始值所需要的。你换个别的就不行了.
  3. 尽管这是一个Set但是最前面的struct关键字表明了他是一个结构体,也就意味着在OC里是不可用的。

使用OptionSet

初始化

当需要创建选项集的实例时,请将该类型的一个静态成员指定给变量或常量。或者,要创建具有多个成员的选项集实例,请为该选项集的多个静态成员分配一个数组。要创建空实例,请为变量指定一个空数组。

let singleOpt: WeaponOptions = .sword
let multipleOpts: WeaponOptions = [.sword, .spear]
let noOpt: WeaponOptions = []

使用操作

我们可以使用与集合相关的操作来检查成员身份,并从自定义选项集合类型的实例中添加或删除成员。例如:

var humOptions: WeaponOptions = []
humOptions.insert(.sword)
if humOptions.contains(.sword) {
     humOptions.remove(.sword)
} else {
}

总结

Swift里位运算依赖于optionSet,利用这个类型,可以进行Set相关的操作。果然还是要多看,多学才会有新知识。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.前言 1.什么是位移枚举? 如我们在写代码中经常用过或者是见过的这种写法的枚举 通过 | (位运算符或)进行组...
    SuDream阅读 9,566评论 0 4
  • 1、Swift 比 Objective-C 有什么优势? Swift 速度更快,运算性能更高。Swift 语法简单...
    凌云01阅读 9,212评论 0 11
  • 原文链接 卓同学的 Swift 面试题 class 和 struct 的区别 class 为类, struct 为...
    PierceDark阅读 8,650评论 8 33
  • class 和 struct 的区别 class 为类, struct 为结构体, 类是引用类型, 结构体为值类型...
    Master_K阅读 4,746评论 0 3
  • 1、随机数 不需要随机数种子 arc4random()%N + begin:产生begin~begin+N的随机数...
    我是小胡胡123阅读 9,743评论 0 2