我正在尝试Swift协议,我遇到了有趣的东西。有很多解决方法,但是有人可以解释下面的错误吗?
protocol UserRenderable {
var name : String { get }
}
protocol PostRenderable {
var title: String { get }
var author: UserRenderable { get }
}
struct User {
let id: String
let name : String
}
struct Post {
let id: String
let title: String
let author: User
}
extension User : UserRenderable {}
extension Post: PostRenderable {}
上述代码(将其放在操场上或其他任何代码(将丢弃汇编错误:
协议要求属性"作者"具有"用户"类型;您想添加一个存根吗?
var作者:userrendarable {get}
这样做的原因是什么?
最佳解决方案不是关联类型。看起来有一个整洁的选项(从答案到另一个问题(:
没有真正的理由为什么不可能,只读 物业需求可以是协变量的,因为返回conformstob 键入为协议的属性的实例完全合法。
Swift当前只是不支持它。为此, 编译器将不得不在协议证人之间产生thunk 表格和符合实现以执行必要的 类型转换。例如,conformstob实例需要 在存在容器中盒装以作为协议b键入 (而且呼叫者无法做到这一点,因为它可能不知道 关于所谓的实现的任何内容(。
但是,再次没有理由为什么编译器不应该做 这个。
事实证明,您可以使用良好的旧 typelias
来进行 trick 编译器进行竞标,而无需编写thunk。此代码无问题编译:
protocol UserRenderable {
var name : String { get }
}
protocol PostRenderable {
var title: String { get }
var author: UserRenderable { get }
}
struct User {
let id: String
let name : String
}
struct Post {
let id: String
let title: String
let author: User
}
extension User : UserRenderable {}
extension Post: PostRenderable {
typealias User = UserRenderable
}
您的Post
结构对author
具有非常特异性的类型。该协议指定PostRenderable
的某些内容需要具有UserRenderable
的作者。虽然所有User
s均为UserRenderable
,但并非所有UserRenderable
项目均为User
。因此,您应该将author
的类型更改为UserRenderable
,而不是User
。