我想我不明白协议(protocol)扩展应该如何工作。
我试过这个:
protocol P {
var h: [String: Any] { set get }
}
extension P {
var h: [String: Any] {
get {
return [:]
}
set {}
}
}
struct S: P {
init() {
self.h = ["o": "o"]
}
}
我的目标是 S
具有 P
的属性,并且不需要在结构定义中重新声明它。
但是,当我创建 let s = S()
时,s.h
始终等于 [:]
而不是 ["o ":"o"]
.
当然,这是因为我的setter是空的,但是我不知道如何去做我想在这里实现的。
感谢您的帮助。
最佳答案
My goal is that S has the properties of P and doesn't need to re-declare it in the struct definition.
这在您尝试执行此操作的方式中是不可能的。协议(protocol)需要某些行为。符合类型必须提供这些行为。如果您需要存储来实现行为,则符合类型必须提供存储。
如果您不需要存储也没关系,那么扩展程序可以像您的一样返回值。但是您不能返回计算值并且也有存储空间。你想做的事是不可能的。您正在考虑类,而不是协议(protocol)。 (如果你想要类,那很好。使用类。它们没有任何问题。)
思考为什么这在 Swift 中不可能的一个好方法是考虑以下情况。假设您的 P
协议(protocol)以某种形式存在,可以实现您想要的。现在在一个模块中我们定义:
struct S {}
这个结构不需要存储。在该模块中对 S()
的任何调用都不会分配任何内容。 (或者,给 S
一些属性,它会分配一些特定数量的内存。)
现在在其他一些模块中,扩展 S
以符合 P
:
extension S: P {}
h
的存储空间在哪里?在加载此扩展时,实例可能已经存在。如果有多个协议(protocol)需要额外的存储并且所有协议(protocol)都附加到 S
会怎么样。 S
结构中的那些属性应该是什么偏移量?该顺序对于编译代码非常重要。这并非不可能解决(ObjC 使用一种称为关联对象的技术来解决),但它是对语言的一个很大的补充,并且阻止了许多重要的优化,而 Swift 不会那样做。
关于Swift 协议(protocol)扩展 : cannot assign to property: '' is a get-only property,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54135006/