swift – 特定于枚举成员的通用约束
发布时间:2020-12-14 04:34:17 所属栏目:百科 来源:网络整理
导读:我有一个关联类型的协议: protocol MyProtocol { associatedtype Q} 现在我想要一个类似的枚举 enum MyEnumQ { case zero case one(MyProtocol) case two(MyProtocol,MyProtocol)} 其中每个关联值都有Q作为其关联类型.这不起作用: enum MyEnumQ { case zer
我有一个关联类型的协议:
protocol MyProtocol { associatedtype Q } 现在我想要一个类似的枚举 enum MyEnum<Q> { case zero case one(MyProtocol) case two(MyProtocol,MyProtocol) } 其中每个关联值都有Q作为其关联类型.这不起作用: enum MyEnum<Q> { case zero case one<P: MyProtocol where P.Q == Q>(P) case two<P1: MyProtocol,P2: MyProtocol where P1.Q == Q,P2.Q == Q>(P1,P2) } 显然,单个枚举成员不能拥有自己的通用约束. 我唯一能想到的是将这些约束移动到枚举声明中,但这会固定相关的类型.为了证明为什么这不是我想要的,这是我希望能够做到的: struct StructA: MyProtocol { typealias Q = Int } struct StructB: MyProtocol { typealias Q = Int } var enumValue = MyEnum.one(StructA()) enumValue = .two(StructB(),StructA()) enumValue = .two(StructA(),StructB()) 有没有解决这个限制的方法? 解决方法
键入擦除.答案总是类型擦除.
你需要的是AnyProtocol类型: struct AnyProtocol<Element>: MyProtocol { typealias Q = Element // and the rest of the type-erasure forwarding,based on actual protocol } 现在您可以创建一个使用它们的枚举 enum MyEnum<Q> { case zero case one(AnyProtocol<Q>) case two(AnyProtocol<Q>,AnyProtocol<Q>) } 有关如何构建类型擦除器的更深入讨论,请参阅A Little Respect for AnySequence. Swift不能将PAT(具有相关类型的协议)作为真实类型甚至抽象类型进行讨论.它们只能是约束.为了将其用作抽象类型,您必须将其提取为类型橡皮擦.幸运的是,这是非常机械的,在大多数情况下并不困难.它是如此机械,最终编译器将有希望为您完成工作.但有人必须建造这个盒子,今天就是你. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |