如果枚举实例是枚举类型,或者它是否已经存在,并且我不知道它是否存在,是否可以创建一个返回布尔值的泛型枚举函数?
我在我的项目中使用了大量的枚举。我经常用相关的值来定义枚举。
简单的例子:
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实现枚举函数或检查计算属性或等效协议的值。
缺点:
相反,我正在寻找一种编写泛型函数的方法,如果枚举实例与枚举大小写匹配,则返回布尔值。可以写一次并应用于所有枚举的东西。类似于Struct和Class类型的泛型函数:
func checkType<T, S> (a: T, _: S.Type) -> Bool {
return a is S // though you could just call this directly
}发布于 2017-03-26 02:19:38
我不认为有一个很好的惯用的方式来实现这一点。想到的唯一一件事是将枚举实例的原始内存与虚拟实例与所需的情况进行比较。
因为我们不关心相关的值,我们只需要要求它们各自的最后一个字节是相同的。
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用你自己的判断来决定这是否是你想要的东西在你的项目。这显然不是一种毫无保留地推荐的技术。
https://stackoverflow.com/questions/43022999
复制相似问题