Swift中符合泛型约束的类型为何无法转换?
为什么你的Swift泛型代码会报错?
我来帮你拆解这个问题,其实核心是对Swift泛型参数的理解偏差~
先看报错的代码为什么不行
protocol AProtocol {} protocol AnotherProtocol {} class AClass: AProtocol, AnotherProtocol {} class Generic<T> where T:AProtocol, T:AnotherProtocol { let prop: T = AClass() // 这里报错 }
这里的泛型参数T是一个类型占位符,它代表的是任意满足「同时符合AProtocol和AnotherProtocol」的类型——它可能是AClass,但也可能是其他后来定义的、同样遵守这两个协议的类型(比如class BClass: AProtocol, AnotherProtocol {})。
你直接把AClass()赋值给T类型的prop,编译器没办法保证当前使用的T就是AClass,毕竟T可以是任何符合约束的类型,所以会抛出「无法将AClass类型转换为指定类型T」的错误。
再看能运行的代码为什么没问题
class Generic<T> where T: AProtocol, T: AnotherProtocol { let prop: T init(withProp prop: T) { self.prop = prop } } let instance = Generic<AClass>(withProp: AClass())
当你创建Generic实例时,明确指定了T就是AClass,此时初始化方法要求传入的参数必须是AClass类型,你传入的AClass()完全匹配这个类型要求,编译器能确定类型一致,所以可以正常编译运行。
额外的解决方案:如果想直接赋值,不用泛型怎么办?
如果你只是需要一个存储「同时符合两个协议的实例」的属性,不需要泛型的话,可以用协议组合类型来定义prop:
class NonGenericClass { let prop: AProtocol & AnotherProtocol = AClass() }
这样prop可以接受任何同时符合AProtocol和AnotherProtocol的实例,AClass()自然是符合要求的,代码也能正常运行。
内容的提问来源于stack exchange,提问作者mike
相关产品推荐
相关产品推荐

