【问题标题】:Redeclaring members in an extension hides the original member *sometimes*. Why?在扩展中重新声明成员*有时*会隐藏原始成员。为什么?
【发布时间】:2018-02-17 19:43:39
【问题描述】:

一次偶然的机会,我发现你可以在编译器不抱怨的情况下做到这一点:

extension Date {
    var timeIntervalSinceNow: TimeInterval {
        return 1000
    }
}

更奇怪的是,这个实际上的计算结果是 1000:

Date().timeIntervalSinceNow
  • 扩展似乎隐藏了原始成员。

所以我尝试用我自己的班级来做到这一点:

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

extension A {
    var a: String {
        return "a"
    }
}
  • 编译失败:“'a' 的重新声明无效”。

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

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

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

Date().description // "XXXX"

你能解释一下为什么会出现子弹头现象吗?

【问题讨论】:

  • 难道Date 可能是旧的Objective-C NSDate 的包装,而您的类/扩展A 是纯Swift?
  • 我试图让A 成为NSObject 的子类,但出现了同样的错误,所以我认为这不是原因。 @rmaddy
  • 模块。您可以像这样跨模块覆盖。不过,不知道如何访问原始成员。
  • @Sweeper:这是一个错误,请在此处查看 matt 的评论:stackoverflow.com/questions/33862414/…

标签: swift swift-protocols dynamic-dispatch member-hiding swift-modules


【解决方案1】:

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

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

【讨论】:

  • 这种行为是否记录在任何地方?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-05
  • 2016-04-26
  • 2016-12-23
  • 2012-06-22
相关资源
最近更新 更多