gpt4 book ai didi

Swift多协议(protocol)一致性,编译错误

转载 作者:行者123 更新时间:2023-12-03 08:29:54 27 4
gpt4 key购买 nike

我有以下协议(protocol):

protocol ProtoAInput {
func funcA()
}

protocol ProtoA {
var input: ProtoAInput { get }
}

protocol ProtoBInput {
func funcB()
}

protocol ProtoB {
var input: ProtoBInput { get }
}

我想让我的 StructC 符合 ProtoAProtoB 协议(protocol),只需一个输入 属性(property)。它本身只是对 self 的引用,因为 StructC 还在单独的扩展中实现了 ProtoAInputProtoBInput

struct StructC: ProtoA, ProtoB {
var input: ProtoAInput & ProtoBInput { return self }
}

extension StructC: ProtoAInput {
func funcA() { print("funcA") }
}

extension StructC: ProtoBInput {
func funcB() { print("funcB") }
}

let s = StructC()
s.funcA()
s.funcB()

Swift 5.3 编译器无法构建此代码,并出现以下错误:

类型“StructC”不符合协议(protocol)“ProtoA”

类型“StructC”不符合协议(protocol)“ProtoB”

这段代码是否违反了任何编译规则?我不明白为什么我不能让 input 变量同时符合这里的两个协议(protocol)。

最佳答案

这是SR-522 (协议(protocol)函数不能有协变返回)。 Swift 只是不支持这一点。如果协议(protocol)需要类型,那么这就是所需的类型。子类也是如此:

class ProtoAInput {}
class ProtoAInputSub: ProtoAInput {}

protocol ProtoA {
var input: ProtoAInput { get } // <=== requires superclass
}

struct StructA: ProtoA {
var input: ProtoAInputSub // <=== So can't use a subclass here
}

理论上,只要所需的属性只是get,编译器就可以支持这一点。如果您添加了set,则此操作不起作用。但今天这对两者都不起作用。

我怀疑,由于 existential containers 的布局,支持这一点会很复杂。 。您不能将 P & Q 放在与 Q 相同的位置(就 Swift 实现而言,而不是就类型理论而言)。见证表中的偏移量将是错误的。感觉像是可以实现的东西,但我明白为什么在不通过额外的间接方式牺牲性能的情况下它会变得复杂。

Swift 类型系统可以支持很多东西,但现在却无法支持。在很多情况下,这并不是因为不可能或者 Swift 团队拒绝了它。只是编译器不支持它们。

关于Swift多协议(protocol)一致性,编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65440493/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com