5

I'm attempting to create a constant that depends on another in the following way:

class Thingy {
 let paddingConstant = 13.0
 let paddingDict = ["padding": paddingConstant]
}

The bottom line gives me an error "Thingy.Type does not have a member named 'paddingConstant'".

Is it possible to declare a constant that depends on another?

Julian B.
  • 3,605
  • 2
  • 29
  • 38
  • Yes thats possible. You need to make paddingDict read only computed property – Zell B. May 20 '15 at 19:08
  • 1
    Possible duplicate of [How to initialize properties that depend on each other](http://stackoverflow.com/questions/25854300/how-to-initialize-properties-that-depend-on-each-other). – Martin R May 20 '15 at 19:19

5 Answers5

9

Another solution is to declare this variable lazy. The advantage is that, unlike a calculated property, it does not perform the calculation every time you fetch its value; but the downside is that it cannot be a constant, unfortunately:

class Thingy {
    let paddingConstant = 13.0
    lazy var paddingDict : [String:Double] = 
        ["padding": self.paddingConstant]
}

I regard that limitation as a bug in the Swift language.

matt
  • 515,959
  • 87
  • 875
  • 1,141
6

You can move paddingDict to the init:

class Thingy {
    let paddingConstant = 13.0
    let paddingDict : [String: Double]
    init() {
        paddingDict = ["padding": paddingConstant]
    }
}
Tim
  • 2,089
  • 1
  • 12
  • 21
4

You can populate an instance constant property a (at definition time) using the value of another constant property b if b is defined static.

class Thingy {
    static let paddingConstant = 13.0
    let paddingDict = ["padding": paddingConstant]
}

This is the direct answer to the error message you got:

Thingy.Type does not have a member named 'paddingConstant'

Infact by making paddingConstant static, it becomes a Type property: part of Thingy.Type.

Hope this helps.

Luca Angeletti
  • 58,465
  • 13
  • 121
  • 148
2

As another solution you can use an outer struct for defining the constant (and other constants you might need):

struct Constants {
    static let paddingConstant = 13.0
}

and then use it in Thingy class:

class Thingy {
  let paddingDict = ["padding": Constants.paddingConstant]
}
giorashc
  • 13,691
  • 3
  • 35
  • 71
0

Yes thats possible. You need to make paddingDict read only computed property

class Thingy {

    let paddingConstant = 13.0

    var paddingDict : [String : Double] {

        get {return ["padding": paddingConstant] }
    }
}
Zell B.
  • 10,266
  • 3
  • 40
  • 49
  • 3
    however this will create a dictionary on every use of paddingDict – giorashc May 20 '15 at 19:15
  • No it wont create a dictionary on every use, but will compute its value on every use and since your paddingDice use another property to compute its value it should be a computed property . You can learn more about computed properties here https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html#//apple_ref/doc/uid/TP40014097-CH14-ID254 – Zell B. May 20 '15 at 19:19
  • 1
    @zellb Can you show where that's explicitly stated? If the property is computed every time, one step of that computation is creating a dictionary. – Brian Nickel May 20 '15 at 19:24
  • Creating new instance mean allocating some memory. Computed properties allocate memory once only and use that memory only for further calculations and thats make a difference – Zell B. May 20 '15 at 19:32
  • @zellb then it was also possible to declare it with 'let' which is more reasonable to indicate a one time memory allocation. But computed properties by their nature change and how exactly can it know if it needs further calculation? – giorashc May 20 '15 at 19:45
  • It would have been nice if swift kept static variables in functions. – Tobias May 20 '15 at 23:57