Bin*_*ian 5 enums swift metatype
给定方法
func enumCaseCount<T: Hashable>(ofType type: T.Type) -> Int {
// Needed check if type is an enum type
return 3
}
Run Code Online (Sandbox Code Playgroud)
使用如下
private enum SimpleEnum: String {
case a = "A"
case b = "B"
case c = "C"
}
enumCaseCount(ofType: SimpleEnum.self)
Run Code Online (Sandbox Code Playgroud)
可以通过这种方式测试类
class Test {}
Test.self is AnyClass // returns true
Run Code Online (Sandbox Code Playgroud)
为了它的乐趣,作为一种(解决方法) hack,我们可以实例化 的实例T并使用Mirror,特别是它的displayStyle属性对其执行运行时自省。在继续之前,我们注意到我们只会将其用于调试目的
镜子由游乐场和调试器使用。
我还要指出,我们实际上是在追尾,因为我们求助于运行时来查询编译时已知的事物(至少是编译器已知的)。
无论如何,首先,我将重命名enumCaseCount(...)为isEnum(...),因为这个问题仅涉及查询元类型是否是 an enum。对于类似(有点脆弱)的黑客来查询给定的案例数enum,请参阅:
现在,通用占位符TinisEnum(...)只知道它是符合 的类型Hashable,这并没有为我们提供任何直接的方法来实例化 的实例T(如果是Hashable蓝图,例如初始化程序init(),我们可以轻松构造 的实例T对其执行运行时内省)。相反,我们将手动为单个T实例分配原始内存 ( UnsafeMutableRawPointer.allocate(bytes:alignedTo:)),将其绑定到T( bindMemory(to:capacity:)),最后deallocate(bytes:alignedTo:)在完成对由指向绑定的指针引用的实例的运行时内省后释放内存 ( )记忆。至于运行时自省,我们只是用来Mirror检查它是否displayStyle存在enum。
func isEnum<T: Hashable>(_: T.Type) -> Bool {
var result = false
// Allocate memory with size and alignment matching T.
let bytesPointer = UnsafeMutableRawPointer.allocate(
bytes: MemoryLayout<T>.size,
alignedTo: MemoryLayout<T>.alignment)
// Bind memory to T and perform introspection on the instance
// reference to by the bound memory.
if case .some(.`enum`) = Mirror(reflecting:
bytesPointer.bindMemory(to: T.self, capacity: 1).pointee)
.displayStyle {
print("Is an enum")
result = true
} else { print("Is not an enum") }
// Deallocate the manually allocate memory.
bytesPointer.deallocate(bytes: MemoryLayout<T>.size,
alignedTo: MemoryLayout<T>.alignment)
return result
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
enum SimpleEnum { case a, b, c }
enum SimpleStrEnum: String {
case a = "A"
case b = "B"
case c = "C"
}
enum SimpleExplicitIntEnum: Int { case a, b, c }
struct SimpleStruct: Hashable {
let i: Int
// Hashable
var hashValue: Int { return 0 }
static func ==(lhs: SimpleStruct, rhs: SimpleStruct) -> Bool { return true }
}
print(isEnum(SimpleEnum.self)) // true
print(isEnum(SimpleStrEnum.self)) // true
print(isEnum(SimpleExplicitIntEnum.self)) // true
print(isEnum(SimpleStruct.self)) // false
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2233 次 |
| 最近记录: |