我的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。对我来说,看起来有些处理会在编译前或编译时从代码中删除具有警告“冗余一致性约束”的约束。
作为Swift语法的构造,我是否遗漏了协议的一些内容?
还是只是编译器的一个bug?
为什么我的代码不可编译?
如何进行可编译?
Xcode 11.3 (11C29),Swift 5
发布于 2020-01-14 16:41:02
编译器就在这里,您确实有一个冗余的一致性,问题是它只有一个位置来删除复制,但是,正如您注意到的那样,它破坏了其他东西。
该问题是由Woman/Man协议族之间的循环引用引起的,因为它们的关联类型受到限制。
Woman.Husband符合Man,Man.Wife符合Women。现在,CoolMan是从Man派生出来的,这意味着CoolMan.Wife已经是Women了。如果指定CoolMan.Wife是CoolWoman,而CoolWomen是Women,则会从两条不同的路径满足Women需求,从而导致冗余编译器警告。
这有点类似于菱形问题,编译器无法选择要遵循的继承路径。
这里的解决方案是找到另一个不围绕这么多循环依赖的设计。就像保留周期一样,您需要在某个地方打破引用链,这个地方取决于您想要用这个设计完成什么。
https://stackoverflow.com/questions/59620879
复制相似问题