在扩展中重新声明成员会隐藏原始成员(有时*)。为什么?

Swe*_*per 5 member-hiding swift

偶然地,我发现您可以在没有编译器抱怨的情况下执行此操作:

extension Date {
    var timeIntervalSinceNow: TimeInterval {
        return 1000
    }
}
Run Code Online (Sandbox Code Playgroud)

奇怪的是,这实际上评估为1000:

Date().timeIntervalSinceNow
Run Code Online (Sandbox Code Playgroud)
  • 该扩展名似乎隐藏了原始成员。

因此,我尝试在自己的课堂上这样做:

class A {
    var a: String {
        return "A"
    }
}

extension A {
    var a: String {
        return "a"
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 并且无法编译:“无效的'a'重新声明”。

我观察到这不会通过协议影响原始成员的使用,这是预期的隐藏行为:

extension Date {
    var description: String {
        return "XXXX"
    }
}

let date: CustomStringConvertible = Date()
date.description // normal date

Date().description // "XXXX"
Run Code Online (Sandbox Code Playgroud)

您能解释为什么会出现子弹头现象吗?

Inf*_*mes 3

这是有效的,因为您是在与原始变量声明不同的模块中声明此扩展。

跨模块的变量名可以被重载,但在我看来,这是 Swift 的一个缺点,因为目前没有办法明确声明你想要哪个模块声明。