Swift元类型检查异常:type(of:)未返回预期动态类型?
核心背景
你在尝试参考旧方案判断泛型变量是否为AnyObject类型时遇到了不符合预期的行为,下面针对你代码中的6个疑问逐一解析:
1. type(of: object)输出Plugin而非P
在泛型结构体ObjectHashable<Plugin>中,object的静态类型被泛型参数T约束为Plugin协议类型。泛型上下文的静态绑定特性会让type(of:)基于静态类型返回元类型,而非实例的真实动态类型。但如果在非泛型环境中直接调用type(of:)(比如let p: Plugin = P(); print(type(of: p))),则会正确返回动态类型P——这是泛型与普通代码的行为差异导致的。
2. t1 is AnyClass结果为false
t1是Plugin.Type(协议元类型),而AnyClass本质是类的元类型(即AnyObject.Type)。即便协议带有AnyObject约束,协议本身并不是类,因此协议元类型无法匹配AnyClass,结果自然为false。
3. T.self输出Plugin符合预期
T被指定为Plugin协议,T.self就是该协议的元类型Plugin.Type,输出与预期一致。
4. t2 is AnyClass结果为false
和第二个疑问原因相同:t2是Plugin.Type(协议元类型),并非类元类型,因此无法被判定为AnyClass。
5. Mirror(reflecting: object).subjectType输出P符合预期
Mirror是Swift专门用于反射实例真实类型的工具,它会绕过静态类型的约束,直接读取实例的动态类型信息,因此能正确返回实际的类P。
6. t3 is AnyClass结果为true
t3是P.Type(类P的元类型),所有类的元类型都属于AnyClass的范畴(因为AnyClass等价于AnyObject.Type),因此结果为true。
可行的解决方案
如果要在泛型上下文中准确判断实例是否为AnyObject类型,可以用以下两种方式:
public struct ObjectHashable<T>: Hashable { public let object: T public init(object: T) { // 方案1:直接通过类型转换判断实例是否为AnyObject let isObjectInstance = object is AnyObject print(isObjectInstance) // 对于P实例会输出true // 方案2:通过Mirror获取真实类型后判断是否为类类型 let realInstanceType = Mirror(reflecting: object).subjectType let isClassType = realInstanceType is AnyClass print(isClassType) // 输出true self.object = object } public static func ==(lhs: Self, rhs: Self) -> Bool { return true } public func hash(into hasher: inout Hasher) { } }
内容的提问来源于stack exchange,提问作者HL666

