繁体   English   中英

具有关联类型的协议中的开放递归有多有限?

[英]How limited is open recursion in protocols with associated types?

我的 Swift 代码有问题。 它无法被编译,因为 swift 在某些协议中看不到关联的类型。 我找到了重现问题的基本最小值,以下代码代表了它。

protocol Woman {
    associatedtype Husband: Man
             where Husband.Wife == Self
}

protocol Man {
    associatedtype Wife: Woman
             where Wife.Husband == Self
}

protocol CoolWoman: Woman //warning
   where Husband: CoolMan {
}

protocol CoolMan: Man
   where Wife: CoolWoman {

    associatedtype Bike: Harley
             where Bike.Owner == Self
}

protocol Harley {
    associatedtype Owner: CoolMan
             where Owner.Bike == Self
}

在此代码编译后,我在标有\\\\warning行中有以下\\\\warning

冗余一致性约束“Self”:“Woman”

它看起来是错误的,因为删除: Woman where Husband: CoolMan使代码无法编译,因此一致性约束不是多余的。 警告使代码不清楚,但(嗯)可以容忍。 但是下面的函数不可编译的事实不容忽视。

func partnerBike<She: CoolWoman>() -> She.Husband.Bike? { //error
    return nil
}

它提供了编译错误:

“丈夫”不是“她”的成员类型

但不是真的丈夫是符合酷女人的她的成员。 对我来说,似乎某些处理在编译之前或编译时从代码中删除了警告“冗余一致性约束”的约束。

我是否错过了作为 Swift 语法构造的协议?
或者它只是编译器的一个错误?
为什么我的代码无法编译?
如何做到可编译?


Xcode 11.3 (11C29),Swift 5

编译器就在那里,你确实有一个冗余的一致性,问题是它只有删除重复的地方,但是正如你注意到的那样破坏了其他东西。

这个问题是由Woman / Man协议系列之间的循环引用引起的,因为它们相关类型的限制。

Woman.Husband符合ManMan.Wife符合Women 现在CoolMan衍生自Man ,也就是说CoolMan.Wife已经是Women 指定CoolMan.WifeCoolWoman ,而CoolWomenWomen会导致从两个不同的路径满足Women要求,因此冗余编译器警告。

这有点类似于菱形问题,编译器无法选择要遵循的继承路径。

这里的解决方案是找到另一种不围绕这么多循环依赖的设计。 与保留循环一样,您需要在某处打破引用链,这个地方取决于您想用这个设计完成什么。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM