Swift Generic枚举函数来检查大小写

时间:2017-03-25 23:06:27

标签: swift

是否有可能创建一个Generic枚举函数,如果枚举实例是一个枚举类型,或者它已经存在并且我不知道它,则返回一个布尔值?

我在项目中使用了大量的枚举。我经常使用关联值定义枚举。

简单示例:

enum Mode {
    case new
    case edit(Record)    // Record is a struct type
}

我会定期检查枚举实例是否是特定的枚举案例。但是,很多时候,我不需要检查相关值。我正在寻找一种检查案例的便捷方式。我所知道的每种方法都有缺点。

方法1-2:如果是案例模式匹配或切换案例

let myMode = Mode.edit
if case Mode.edit(_) = myMode {
    // do something
}

switch mode {
case .edit:
    // do something
default:
    break    
}

下行:

  • 无法直接将检查分配给变量。必须在关闭时这样做
  • 不能直接将此模式用作函数的参数

方法3-5实现枚举函数或检查计算属性或等于协议的值

缺点:

    必须为每个枚举类型实施

相反,我正在寻找一种编写Generic函数的方法,如果枚举实例与枚举情况匹配,则返回布尔值。可以写一次并应用于所有枚举的东西。与结构和类类型的通用函数类似:

func checkType<T, S> (a: T, _: S.Type) -> Bool {

    return a is S   // though you could just call this directly
}

1 个答案:

答案 0 :(得分:1)

我不认为有一种很好的惯用方法可以实现这一目标。我唯一想到的是将枚举实例的原始内存与假实例进行比较。

由于我们不关心相关值,我们只需要要求它们各自的最后一个字节相同。

func unsafeEqualityLastByteOnly<A>(_ lhs: A, _ rhs: A) -> Bool {
    var (lhs, rhs) = (lhs, rhs)

    let offset = MemoryLayout<A>.size - 1

    return withUnsafePointer(to: &lhs) { lhsPtr in
        withUnsafePointer(to: &rhs) { rhsPtr in
            let lhsPtr = unsafeBitCast(lhsPtr, to: UnsafeRawPointer.self)
            let rhsPtr = unsafeBitCast(rhsPtr, to: UnsafeRawPointer.self)

            return memcmp(lhsPtr.advanced(by: offset), rhsPtr.advanced(by: offset), 1) == 0
        }
    }
}

这很不错,但它确实有用。

enum Test {
    case a(Int)
    case b(Int)
}

let a1 = Test.a(1)
let a2 = Test.a(2)

let b1 = Test.b(1)
let b2 = Test.b(2)

unsafeEqualityLastByteOnly(a1, a1) // true
unsafeEqualityLastByteOnly(a1, a2) // true
unsafeEqualityLastByteOnly(a2, a2) // true

unsafeEqualityLastByteOnly(b1, b1) // true
unsafeEqualityLastByteOnly(b1, b2) // true
unsafeEqualityLastByteOnly(b2, b2) // true

unsafeEqualityLastByteOnly(a1, b1) // false
unsafeEqualityLastByteOnly(a1, b2) // false
unsafeEqualityLastByteOnly(a2, b1) // false
unsafeEqualityLastByteOnly(a2, b2) // false

使用您自己的判断来决定这是否是您在项目中想要的东西。它显然不是一种应该在没有任何保留的情况下推荐的技术。