user2727195
user2727195

Reputation: 7330

Struct static vars under inheritance

how the ambiguity can be resolved in this case provided that I can't change the name Static and the name SOMECONST for each class (to keep a consistent convention across the API classes)

it might or might not work in playgrounds but the error AMBIGUOUS USE OF SOMECONST appears during compilation in Xcode.

If it's not possible then I'm going to revert to getters, any person got an idea if Apple will implement static for classes or it's only designed for struct and enum???

public class A {

    public struct Static {
        public static let SOMECONST = 1
    }

    init(val: Int) {
        println(val)
    }
}

public class B: A {

    public struct Static {
        public static let SOMECONST = 2
    }

    init() {
        super.init(val: B.Static.SOMECONST)
    }

}

B()

Upvotes: 2

Views: 885

Answers (1)

akashivskyy
akashivskyy

Reputation: 45200

The program (unsurprisingly) can't compile because it found two candidates for the SOMECONST symbol:

error: ambiguous use of 'SOMECONST'
    super.init(val: B.Static.SOMECONST)
                      ^
note: found this candidate
    static let SOMECONST = 2
               ^
note: found this candidate
    static let SOMECONST = 1
               ^

Using nested types for storing constants like this is generally a bad idea, because nested types can't be overriden by subclasses. You should declare the constants directly as part of your class.

Now, ideally you would do something like this:

class A {
    class let SOMECONST = 1
}

class B: A {
    override class let SOMECONST = 2
}

But, unfortunately, this is not supported by the current Swift compiler. The only way you can override a class (static) variable is to make it computable:

class A {
    class var SOMECONST: Int {
        return 1
    }
}

class B: A {
    override class var SOMECONST: Int {
        return 2
    }
}

That's a little bit uglier, but it works. You can now create your B's initializer:

init() {
    super.init(val: B.SOMECONST) // prints "2"
}

Upvotes: 1

Related Questions