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

问题描述 投票:0回答:1

我的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标记了以下警告:

冗余一致性约束“自我”:“女人”

这看起来是错误的,因为删除: Woman where Husband: CoolMan会使代码不可编译,因此一致性约束不是多余的。警告使代码不清楚,但是(可以)可以接受。但是以下函数不可编译的事实不能忽略。

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

它提供编译错误:

'丈夫'不是'她'的会员类型

但是丈夫并非是符合CoolWoman的She的成员。对我来说,似乎有些处理在编译前或编译时从代码中删除了警告“冗余一致性约束”的约束。

我是否想念有关Swift语法的协议?还是仅仅是编译器的一个错误?为什么我的代码无法编译?如何编译?


Xcode 11.3(11C29),Swift 5

swift swift-protocols
1个回答
0
投票

编译器就在那儿,您确实具有冗余一致性,问题在于,它只有地方可以删除重复项,但是正如您所注意到的,它破坏了其他内容。

问题是由于Woman / Man协议系列之间的循环引用,由于它们的关联类型受到限制。

Woman.Husband符合ManMan.Wife符合Women。现在CoolMan是从Man派生的,这意味着CoolMan.Wife已经是Women。指定CoolMan.WifeCoolWomanCoolWomenWomen会导致从两个不同的路径满足Women要求,因此冗余编译器警告。

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

这里的解决方案是找到另一种不涉及那么多循环依赖关系的设计。与保留周期一样,您需要在某个地方断开引用链,而这个地方取决于您要使用此设计完成的工作。

© www.soinside.com 2019 - 2024. All rights reserved.