Same name allowed for both static and instance member?

I always wonder why Swift require full qualification for accessing static property/method. I realize the same name can be used for both static and instance member. I think this is not the case for C++ and Java?

Why does Swift make this choice? How is the same name for both static and instance member useful and not confusing?

protocol P { }

struct S: P { }

extension P where Self == S {
    static var staticProp: S { .init() }
}

struct Foo {
    static let abc = 123
    let abc = 444

    func bar(_ v: P) {
        let _ = 2 * Self.abc + abc
    }

    func baz() {
        bar(.staticProp)
    }

    static func baz() {
    }
}

i'm actually glad that swift allows the same name for static and instance members (i remember i had to invent some prefixes for static members back in C++).

classic example Thread.isMainThread vs thread.isMainThread.

"why Swift require full qualification for accessing static members" is slightly different question. in theory swift could have only require this prefix if there was a potential collision. imho not a big deal either way, just prepend the name with a type name or even "Self."

I usually use Self., unless when it's outside of the struct or nested struct. To avoid very long name prefix in nested struct, I found nested enum works:

struct FooVeryVeryVeryLooooooooooooooooooooooooooooooogName {
    static let xxx = 123

    enum Metrics {
        static let xxx = 123
    }

    struct Nested {
        func foo() {
            FooVeryVeryVeryLooooooooooooooooooooooooooooooogName.xxx  // cannot prefix with Self., but the name is so very long :(
            Metrics.xxx     // okay, this is short
        }
    }
}
1 Like