背景
大家在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个要注意的事情
- rawValue属性的类型必须符合FixedWidthInteger协议,比如 你不能拿String来用。
- rawValue这个行是Set定义他自己的原始值所需要的。你换个别的就不行了.
- 尽管这是一个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相关的操作。果然还是要多看,多学才会有新知识。