Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compilation error when using lazy variable

Tags:

I am trying to understand how lazy works in swift. The following code compiles without any error.

import UIKit
class Test : UIViewController{
    let i = 1
    lazy var j:Int =  self.i
}

Whereas if I remove the type of j and make it inferred like the code below,

import UIKit
class Test : UIViewController{
    let i = 1
    lazy var j =  self.i
}

I get compilation error "Value of type 'NSObject -> () -> Test' has no member 'i'"

Can someone explain what is going on with the compiler. Thanks

like image 398
Naveen Ramanathan Avatar asked Jul 20 '16 05:07

Naveen Ramanathan


1 Answers

You need to consider 3 aspects here.

  • A lazy stored property is a property whose initial value is not calculated until the first time it is used. That is when you call the property for the first time its value will be calculated.
  • As the actual value is created by evaluation, you need to declare lazy variable's data type up front.
  • The properties you declare in your class are the instance variables, if you need to access their values you need an instance(object) of the class.

Let us consider following line from your non working code

lazy var j =  self.i

Two problems are present in your non working code. First is you have not specified the data type of your lazy var. As the declaration is incomplete compiler won't treat 'j' as lazy var it will treat is as normal instance variable. You must be aware about swift's rule that whenever you declare any variable in the class you must assign some value to it or else you can make that variable optional. In above statement you are trying to assign i's value to j by using self within the class. When compiler is compiling that line no object of the class is created and the self you are using is nil that is why compiler is throwing the error(It will throw error even if you don't use self due to the same reason mentioned above).

Why it is not causing problems in your working code:

lazy var j:Int =  self.i

As I have mentioned above the value to lazy var is assigned when you call that variable. How will you call that variable out side the class? Of course by creating object. And when you will call it with the help of object 'self' will point to the same object and self won't be nil it won't cause any problem.

In short two things you need to understand 3 things

  • While declaring lazy var you have to specify the data type
  • lazy var is not assigned when it is declared, it is assigned when it is called
  • you can not call instance var without instance(object) of your class
like image 164
Aditya Avatar answered Sep 28 '22 01:09

Aditya