Swift中如何检测可选嵌套结构体的协议一致性?
Swift中检测可选类型嵌套结构体是否遵循协议的问题与解决方法
当检测Swift中嵌套的可选类型结构体是否遵循某协议时,直接使用type(of:)会返回false,即便该结构体本身确实遵循协议。
问题复现代码
protocol XYZ {} extension XYZ { func test() { print("asdsfd") } } struct Test1: XYZ { var test2: Test2 var test3: Test3? init(){ self.test2 = Test2() self.test3 = Test3() } } struct Test2: XYZ {} struct Test3: XYZ {}
检测结果差异
创建实例后,非可选的嵌套结构体检测正常:
let x = Test1() print(type(of: x.test2) is XYZ.Type) // 输出 true
但可选类型的检测返回false:
print(type(of: x.test3) is XYZ.Type) // 输出 false
问题原因
x.test3的实际类型是Optional<Test3>(即Test3?),而Optional本身并未遵循XYZ协议,直接检测可选类型的元类型自然无法匹配XYZ.Type。
解决方法
1. 安全解包后检测
如果可选值已被赋值,先解包再检测内部类型:
if let test3 = x.test3 { print(type(of: test3) is XYZ.Type) // 输出 true }
2. 不解包检测包装类型
通过Optional的关联类型获取内部类型,再判断是否遵循协议:
if let optionalType = type(of: x.test3) as? Optional.Type { let wrappedType = optionalType.wrappedType print(wrappedType is XYZ.Type) // 输出 true }
也可以用泛型封装成通用方法:
func doesWrappedTypeConformTo<T, P>(_ optional: T?, _ protocol: P.Type) -> Bool { return T.self is P.Type } print(doesWrappedTypeConformTo(x.test3, XYZ.self)) // 输出 true
3. 直接进行协议类型转换
如果只需判断可选值内部实例是否遵循协议,直接尝试类型转换即可:
print(x.test3 as? XYZ != nil) // 输出 true
若内部类型遵循协议,x.test3 as? XYZ会返回非空的XYZ?实例。
内容的提问来源于stack exchange,提问作者Pradeep Jalakam
相关产品推荐
相关产品推荐

