Search code examples
swiftvarlazy-initializationlet

Lazy Var vs Let


I want to use Lazy initialization for some of my properties in Swift. My current code looks like this:

lazy var fontSize : CGFloat = {
  if (someCase) {
    return CGFloat(30)
  } else {
    return CGFloat(17)
  }
}()

The thing is that once the fontSize is set it will NEVER change. So I wanted to do something like this:

lazy let fontSize : CGFloat = {
  if (someCase) {
    return CGFloat(30)
  } else {
    return CGFloat(17)
  }
}()

Which is impossible.

Only this works:

let fontSize : CGFloat = {
  if (someCase) {
    return CGFloat(30)
  } else {
    return CGFloat(17)
  }
}()

So - I want a property that will be lazy loaded but will never change. What is the correct way to do that? using let and forget about the lazy init? Or should I use lazy var and forget about the constant nature of the property?


Solution

  • This is the latest scripture from the Xcode 6.3 Beta / Swift 1.2 release notes:

    let constants have been generalized to no longer require immediate initialization. The new rule is that a let constant must be initialized before use (like a var), and that it may only be initialized: not reassigned or mutated after initialization.

    This enables patterns like:

    let x: SomeThing
    if condition {
        x = foo()
    } else {
        x = bar()
    }
    
    use(x)
    

    which formerly required the use of a var, even though there is no mutation taking place. (16181314)

    Evidently you were not the only person frustrated by this.