Search code examples
swiftinitializationinitoption-typeoptional-variables

Swift optional initialisation


It's my understanding that

var perhapsInt : Int?

This is automatically set to a .None value. And the below code snippet confirms that (no compiler errors)

class MyClass {
    var num1: Int = 0
    var num2: Int?

    init(num1: Int) {
        self.num1 = num1
    }
}

var newClass = MyClass(num1: 5)
newClass.num1 // prints '5'
newClass.num2 // prints 'nil'

Is my understanding of the optional initialisation process correct? if so why does this not work when I change num2 to let.

I was expecting the same behaviour of optionals defaulting to nil when using let. Am I missing something here?

class MyClass {
    var num1: Int = 0
    let num2: Int?

    init(num1: Int) {
        self.num1 = num1
        // compiler error : return from initialiser without initialising all stored properties 
    }
}    
...

My question is, how can both of these cases be true. Shouldn't it be one or the other. Either optional values are automatically set to .None or it's not.


Solution

  • The behavior of var num2: Int? is caused by Optionals being sugar-powered. They're the only type in Swift which has an implicit default value (of .None).

    Notice that if you type var num2: Int (without ?) – the compiler will throw the same error, regardless of using var vs. let.

    class MyClass {
        var num2: Int
        init() {
            // Return from initializer without initializing all stored properties
        }
    }
    

    Because lets' values cannot be overwritten (as opposed to vars'), they require you to explicitly set their initial value:

    class MyClass {
        let num2: Int? = nil
    }
    
    // or this way
    
    class MyClass {
        let num2: Int?
        init() {
            num2 = nil
        }
    }
    

    This will, however, result in an useless nil constant.


    You can read more about initialization of stored properties here and here.