Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redeclaring members in an extension hides the original member *sometimes*. Why?

By chance, I discovered that you can do this without the compiler complaining:

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

What's weirder, is that this actually evaluates to 1000:

Date().timeIntervalSinceNow
  • The extension seems to hide the original member.

So I tried to do this with my own class:

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

extension A {
    var a: String {
        return "a"
    }
}
  • and it fails to compile: "invalid redeclaration of 'a'".

I observed that this does not affect the usage of the original member through a protocol, which is expected behaviour of hiding:

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

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

Date().description // "XXXX"

Can you explain why does the bullet pointed phenomena occur?

like image 699
Sweeper Avatar asked Sep 08 '17 20:09

Sweeper


1 Answers

This works because you are declaring this extension in a separate module from the original variable declaration.

Across modules a variable name can be overloaded but in my mind this has been a shortcoming of Swift as there is currently no way to explicitly state which module declaration it is that you want.

like image 132
Infinity James Avatar answered Nov 15 '22 04:11

Infinity James