使用受约束的RawValue扩展OptionSet的正确方法

时间:2017-06-29 17:34:00

标签: swift swift-protocols

我有一个OptionSet,我希望能够执行按位操作(BitwiseOperation协议中的操作)。我写了一个扩展我的类型,然后意识到我应该使它成为可重用的代码。我花了一段时间才找到方法,而我所做的是制作一个从两个协议继承的协议,并在相关类型上添加约束,然后提供默认实现的协议扩展。

它有效,但我的问题是:这是实现这一目标的最佳方法吗?

protocol BitwiseOptionSet : BitwiseOperations, OptionSet {
    associatedtype RawValue : BitwiseOperations, ExpressibleByIntegerLiteral
}
extension BitwiseOptionSet {
    static var allZeros : Self {
        return Self(rawValue: 0)
    }
    prefix static func ~(x: Self) -> Self {
        return Self(rawValue: ~x.rawValue)
    }
    static func ^(lhs: Self, rhs: Self) -> Self {
        return Self(rawValue: lhs.rawValue ^ rhs.rawValue)
    }
    static func &(lhs: Self, rhs: Self) -> Self {
        return Self(rawValue: lhs.rawValue & rhs.rawValue)
    }
    static func |(lhs: Self, rhs: Self) -> Self {
        return Self(rawValue: lhs.rawValue | rhs.rawValue)
    }
}

1 个答案:

答案 0 :(得分:0)

您可以使用OptionSet

的约束扩展RawValue
extension OptionSet where RawValue: BitwiseOperations {
    static var allZeros : Self {
        return Self(rawValue: .allZeros)
    }
    prefix static func ~(x: Self) -> Self {
        return Self(rawValue: ~x.rawValue)
    }
    static func ^(lhs: Self, rhs: Self) -> Self {
        return Self(rawValue: lhs.rawValue ^ rhs.rawValue)
    }
    static func &(lhs: Self, rhs: Self) -> Self {
        return Self(rawValue: lhs.rawValue & rhs.rawValue)
    }
    static func |(lhs: Self, rhs: Self) -> Self {
        return Self(rawValue: lhs.rawValue | rhs.rawValue)
    }
}

请注意,要求符合ExpressibleByIntegerLiteral 可以使用Self(rawValue: .allZeros)代替 Self(rawValue: 0)

示例:

struct MyOptionSet: OptionSet {
    let rawValue: UInt16
    init(rawValue: UInt16) {
        self.rawValue = rawValue
    }
}

let a = MyOptionSet(rawValue: 3)
let b = MyOptionSet(rawValue: 5)
let c = a & b
print(c.rawValue) // 1