gpt4 book ai didi

swift - 为什么协议(protocol)中的仅获取属性要求不能通过符合的属性来满足?

转载 作者:行者123 更新时间:2023-11-30 12:01:40 24 4
gpt4 key购买 nike

为什么下面的代码会产生错误?

protocol ProtocolA {
var someProperty: ProtocolB { get }
}

protocol ProtocolB {}
class ConformsToB: ProtocolB {}

class SomeClass: ProtocolA { // Type 'SomeClass' does not conform to protocol 'ProtocolA'
var someProperty: ConformsToB

init(someProperty: ConformsToB) {
self.someProperty = someProperty
}
}

The answer in this similar question说得通。但是,在我的示例中,该属性是仅获取的。为什么这不起作用?这是 Swift 的缺点,还是有什么理由这样做?

最佳答案

没有真正的理由说明为什么这是不可能的,只读属性要求可以是协变的,因为返回 ConformsToB来自类型为 ProtocolB 的属性的实例完全合法。

Swift 目前不支持它。为此,编译器必须生成 a thunk协议(protocol)见证表和一致性实现之间的关系,以便执行必要的类型转换。例如,ConformsToB实例需要装箱in an existential container以便输入为 ProtocolB (调用者无法执行此操作,因为它可能不知道有关被调用的实现的任何信息)。

但是,编译器没有理由不能执行此操作。有多个关于此问题的错误报告已公开,this one这是特定于只读属性要求的,并且 this general one ,其中 Swift 团队成员 Slava Pestov 说道:

[...] we want protocol witnesses and method overrides in every case where a function conversion is allowed

因此,它看起来确实像是 Swift 团队希望在该语言的 future 版本中实现的东西。

但与此同时,如@BallpointBen says ,一种解决方法是使用 associatedtype :

protocol ProtocolA {
// allow the conforming type to satisfy this with a concrete type
// that conforms to ProtocolB.
associatedtype SomeProperty : ProtocolB
var someProperty: SomeProperty { get }
}

protocol ProtocolB {}
class ConformsToB: ProtocolB {}

class SomeClass: ProtocolA {

// implicitly satisfy the associatedtype with ConformsToB.
var someProperty: ConformsToB

init(someProperty: ConformsToB) {
self.someProperty = someProperty
}
}

但这很不令人满意,因为这意味着 ProtocolA不再可用作类型(因为它有 associatedtype 要求)。它还改变了协议(protocol)的内容。原来是这样说的someProperty可以返回符合 ProtocolB任何 – 现在它说 someProperty 的实现仅处理一种符合 ProtocolB特定具体类型.

另一种解决方法是定义一个虚拟属性以满足协议(protocol)要求:

protocol ProtocolA {
var someProperty: ProtocolB { get }
}

protocol ProtocolB {}
class ConformsToB: ProtocolB {}

class SomeClass: ProtocolA {

// dummy property to satisfy protocol conformance.
var someProperty: ProtocolB {
return actualSomeProperty
}

// the *actual* implementation of someProperty.
var actualSomeProperty: ConformsToB

init(someProperty: ConformsToB) {
self.actualSomeProperty = someProperty
}
}

这里,我们本质上是为编译器编写 thunk,但它也不是特别好,因为它向 API 添加了不必要的属性。

关于swift - 为什么协议(protocol)中的仅获取属性要求不能通过符合的属性来满足?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47141078/

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