0

As common, many swift developers initialize lazy variables by lambda execution. But I can't understand why they use lambda when it is one line of computation. What is the different between the following code examples?

var x = 7
var y = 9
lazy var z = x * y
var x = 7
var y = 9
lazy var z: Int = { 
    return x * y 
}()

I am new in swift, and from a naïve point of view the difference looks like that:

  • the first one sample computes x * y immediately but initializes value by the lazy way
  • the second one sample computes and initializes by the lazy way.

Is it correct?


This question isn't duplication of What is the advantage of closure stored property Initialisation? because it is about lazy computation.

Valentyn Zakharenko
  • 2,710
  • 1
  • 21
  • 47
  • Style choice? I mean you can use lambdas on normal properties as well. – Sweeper Mar 16 '19 at 07:37
  • 1
    Possible duplicate of [What is the advantage of closure stored property Initialisation?](https://stackoverflow.com/questions/49571059/what-is-the-advantage-of-closure-stored-property-initialisation) – denis_lor Mar 16 '19 at 08:30
  • 1
    Customization obviously. The reasons in the proposed duplicate are the same – Sulthan Mar 16 '19 at 09:06
  • When I googled 'lazy in swift' I found `{ ... }()` without object customization as the common case in the top link and in many other descriptions. Now I understand that there is no difference. But only the link to duplication question (that I couldn't google before) in combination with comments explained me the difference. But ok, I voted to close question. – Valentyn Zakharenko Mar 16 '19 at 09:25

1 Answers1

2

People who do it the second way are making a mistake, that’s all.

The mistake is an easy one. Sometimes (1) a define-and-call initializer is necessary, namely when you need multiple code statements to obtain the initial value of a variable:

let timed : Bool = {
    if val == 1 {
        return true
    } else {
        return false
    }
}()

Sometimes (2) you need lazy initialization, namely in order to mention self during property initialization:

lazy var arrow : UIImage = self.arrowImage()

And sometimes (3) you need both together to do both things:

lazy var prog : UIProgressView = {
    let p = UIProgressView(progressViewStyle: .default)
    p.alpha = 0.7
    p.trackTintColor = UIColor.clear
    p.progressTintColor = UIColor.black
    p.frame = CGRect(x:0, y:0, width:self.view.bounds.size.width, height:20)
    p.progress = 1.0
    return p
}()

So it is natural out of habit, misunderstanding, or abundance of caution to resort to form 3 when in fact there was only one line and all you needed was form 2. It’s an easy mistake and does no harm.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • 'People who do it the second way are making a mistake, that’s all.' - google 'lazy in swift' and see that 3 of 4 top links (exclude docs.swift.org) contain this mistake https://www.google.com/search?q=lazy+in+swift&oq=lazy+in+swift. (actual for March 16, 2019) Thank you, your answer that is what I needed. But I had voted to close this question. – Valentyn Zakharenko Mar 16 '19 at 09:40
  • I retracted vote to close I didn't know about this ability. – Valentyn Zakharenko Mar 16 '19 at 09:48
  • Well, I prefer my own explanation to what google may say. See http://www.apeth.com/swiftBook/ch03.html#_lazy_initialization (where these examples come from) and http://www.apeth.com/swiftBook/ch04.html#_properties – matt Mar 16 '19 at 09:49
  • my first 4 links: 1. https://medium.com/@abhimuralidharan/lazy-var-in-ios-swift-96c75cb8a13a 2. https://www.hackingwithswift.com/example-code/language/what-are-lazy-variables 3. https://mikebuss.com/2014/06/22/lazy-initialization-swift/ 4. https://docs.swift.org/swift-book/LanguageGuide/Properties.html - it is when I googled as an anonymous, but when I googled from my account(I am a newcomer in swift) - the 4th link is 2nd. I didn't read docs.swift.org link because of my project is in swift 4.2 but topic about swift 5. – Valentyn Zakharenko Mar 16 '19 at 10:04