Swift optional initialisation

9.7k Views Asked by At

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.

2

There are 2 best solutions below

2
akashivskyy On BEST ANSWER

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.

1
katleta3000 On

I think that a lot of discussion is here. A statement from that thread - look deeper in the link above

The value of a constant doesn’t need to be known at compile time, but you must assign it a value exactly once.

Intresting that you code will compile if you set let value like:

let num2: Int? = .None
let num2: Int? = nil