Swift中如何为关联类型添加协议约束?
Swift协议关联类型约束问题:如何允许协议作为关联类型满足协议约束
问题核心是当给R协议的关联类型NType添加: N约束后,M1中使用[N]作为n的类型会报错,原因是Swift中协议本身并不遵循自己,N作为协议类型,无法满足NType: N的约束(该约束要求NType是遵循N的具体类型)。
解决方案(Swift 5.7+)
使用Swift 5.7引入的any关键字表示存在类型,同时调整协议约束,确保NType可以是任意遵循N的类型(包括存在类型):
protocol N: AnyObject { } class N1: N { } class N2: N { } protocol R { associatedtype NType: AnyObject, N var n: [NType] { get set } } class M1: R { // 使用any N表示任意遵循N的对象类型 var n: [any N] = [N1(), N2()] } class M2: R { var n: [N1] = [N1(), N1()] }
原理说明
any N是存在类型,代表任意遵循N的具体对象类型,它满足AnyObject, N的约束;- 给
N协议添加AnyObject约束是因为我们的实例都是类(N1、N2是类),确保any N只能引用类实例; - 这样
M1的n可以存放不同的N协议遵循者,M2的n则只能存放N1实例,完全符合需求。
替代方案(兼容旧Swift版本)
如果无法使用Swift 5.7+,可以调整R协议的设计,通过扩展添加约束:
protocol N { } class N1: N { } class N2: N { } protocol R { associatedtype NType var n: [NType] { get set } } // 扩展约束:所有遵循R的类型,其NType要么是N,要么是遵循N的具体类型 extension R where NType: N { } class M1: R { var n: [N] = [N1(), N2()] } class M2: R { var n: [N1] = [N1(), N1()] }
这种方式既保留了M1使用[N]的能力,又确保了所有遵循R的类型的NType符合N相关的类型要求。
内容的提问来源于stack exchange,提问作者Jan12
相关产品推荐
相关产品推荐

