# Lazy and Static Variables

#### Lazy Variables

This is an advanced and niche variable type that can help tidy up your code, but you can get by without understanding it.&#x20;

Imagine you have some class with a top-level variable declaration:

```swift
class MyClass {

    let myVariable = <insert expression>

}
```

Whenever that class is initialized, the expression will be evaluated to a value, and that value will be bound to the identifier `myVariable`. This is great unless that expression relies on `self`. Since this computation is occurring at initialization, `self` is not accessible because it is not done being created. It may be missing fields, properties, whatever. It is not safe to use, so the compiler will get mad at you for using `self` before it is accessible.&#x20;

When designing UI, this can often result from trying to set a delegate to self (`myVariable.delegate = self`), but it can also occur anytime you try to access another field or method in the expression to be evaluated. You can solve this with assignment in the initializer:

```swift
class MyClass {
    
    let myVariable: someType
    
    init(...) {
        myVariable = <expression>
        ...
    }
}
```

You can also solve this by making the variable type optional `var myVariable: someType?` (or an implicitly unwrapped optional `var myVariable: someType!`) and assigning it in a function that will be called in the class's normal lifecycle–maybe `viewDidLoad`.&#x20;

Even better than using the latter technique would be to assign an expression and then update it later with the proper fields/methods, so you can avoid optionals entirely. Let's say you are using a view that needs a delegate. If the delegate can be assigned to the view after initialization (which is normally the case) you can create the initial view on init, and then update it with `self` later.

```swift
class MyClass: MyViewDelegate {

    let myVariable = MyView()
    
    init(...) {
        <all initialization work>
        myVariable.delegate = self
    }

}
```

These are all valid solutions that people use frequently. For stylistic reasons, you may be dissuaded from such techniques–it's not ideal to spread your variable setup across places if possible. Equally valid, you may not like to pollute your init or whatever function with variable setup.

Okay, so how would I fix this? The original problem is that you are trying to access `self` before it is ready to access... so don't! We can declare a variable (not a constant) to be `lazy`, which means that it will only be evaluated when it is needed–the first time it is referenced. This means that the variable will always be ready when we ask for it (no risks of optionals not being assigned) at the cost of some computation occurring later in the class's life cycle instead of on initialization–but this is not going to be noticeable unless you are doing some heavy computation.&#x20;

```swift
class MyClass: MyViewDelegate {

    lazy var myVariable = MyView(delegate: self)

}
```

Often when using Apple's UIKit framework, you can initialize the view, and `self` does not show up until you are trying to configure your view. This lends itself well to the technique of initializing the view and doing setup later in the init function or some other function that you can guarantee will be called before you need the variable. But again, this has the issue of spreading code out and potentially polluting functions with extra setup. We can refactor such code by creating a closure block (anonymous function) that will setup up the object and then return it–see more about anonymous functions on the `Functions` page.&#x20;

There are a few things to note with this technique:

1. If you create a new variable in the closure, it must have a different name than the lazy variable that it will be assigned to because the compiler will get mad about referencing a variable that has yet to be initialized–just like what was happening with `self` before!&#x20;
2. If you are using a closure, you will need to give the variable an explicit type because the compiler is not good at figuring out types for closures
3. You must call the function that returns the value

```swift
class MyClass: MyViewDelegate {
    
    lazy var myVariable: MyView = {
        let view = MyView()
        view.delegate = self
        return view
    }()
    
}
```

### Static Variables

When creating classes and structs, it may make sense to store values and functions within the overarching data type and not the objects (store them in the original class or struct instead of the objects they create). One special example of this is the `init` function. It makes no sense for it to be stored in the object because it would **require** an object to make another one–there would also be no first instance, so there would be no instances ever. This is why we can do `<ClassName>.init` or `<StructName>.init`. Of course, there are other things that we may want to access in a similar manner. To do this for, variables, constants, and functions, you do everything as you normally would but with the `static` keyword beforehand.

One common use of static functions is infix functions. These functions let us do comparisons like equality in our code without doing ugly things like accessing methods. Using our implementation of `Fraction` with fields `numerator: Int`, `denominator: Int` and computed property `decimal: Float` (defined in the `Variable Properties` page) we can write a function for equality:

```swift
extension Fraction {

    static func == (_ lhs: Fraction, _ rhs: Fraction) -> Bool {
        return lhs.decimal == rhs.decimal
    }

}
```

It is convention for infix operators to use anonymous parameters and the lhs (left-hand side) rhs (right-hand side) notation for Swift, but these can be replaced with whatever you want.

You'll also find static variables in the wild quite a lot. You may have noticed when using `UIColor` or `NSColor`, if a variable has one of those as its type, you can just write .red, .blue, or some other built-in color. This is because of static variables! Since the compiler knows the type, if you start the expression with `.`, the compiler will assume you are looking within that type, and what's in that type, well everything that's stored in the class. This works for Enums too!


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ios-course.cornellappdev.com/resources/swift-foundations/constants-and-variables/lazy-and-static-variables.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
