为什么允许它在扩展中重新声明Swift内置类型的计算属性,而不允许它重新声明我的自定义类型的计算属性?
struct X {
var isEmpty: Bool { true }
}
extension X {
var isEmpty: Bool { true } // error: invalid redeclaration of 'isEmpty'
}
extension String {
var isEmpty: Bool { true } // allowed
}发布于 2022-04-02 19:24:31
这是故意的,但一般情况下你不应该这么做。允许从另一个模块导入的原因是,如果更改模块以创建新属性,则防止工作代码中断。例如,考虑添加自己的属性的情况:
extension String {
var isX: Bool { self == "x" }
}这是合法的,这不足为奇。但是,如果这是一个好主意,太棒了,以至于他们把它添加到stdlib中呢?那么你的代码应该中断吗?如果他们将其在stdlib中实现为self.lowercased == "x",那么它与您的略有不同吗?
这是ObjC中的一个主要问题。事实上,这件事发生了很多次,而且可能导致奇怪的、不明确的行为。(在我的…时代,我不得不追踪这些bug中的几个)Swift的回答是,扩展适用于它的上下文。因此,在您的模块中,您的isEmpty应用。但是在stdlib中,stdlib isEmpty适用。您没有覆盖它;您只是在创建您自己的本地扩展。
当然,这也有一些不利因素。这意味着您可能无意中隐藏了一个符号,这可能会给以后的开发人员造成混乱。但这是我们目前的选择。你绝对不应该故意这么做。这是否应该是一个警告是另一个问题。
有关更多历史信息,请参见Swift论坛中的允许通过扩展修改导入类型的方法/属性吗?。
https://stackoverflow.com/questions/71717477
复制相似问题