Swift optional initialisation
Asked Answered
C

2

6

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.

Connor answered 15/11, 2015 at 11:10 Comment(0)
F
7

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.

Friedland answered 15/11, 2015 at 11:31 Comment(2)
Okay that make sense. Thanks. As a follow up question, why does it work when I initialiser a 'let' inside 'init' but not initialise when I define it? see this block of code. class MyClass { let num2: Int? init() { self.num2 = nil } } shouldn't this throw an error around 'let num2: Int?' lineConnor
No. let only requires you to assign the value once, no more, no less. When talking about initializers, they require all lets to have a value before initialization finishes. Therefore you may do this either via default value, or in the initializer itself.Friedland
I
1

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
Inbeing answered 15/11, 2015 at 11:25 Comment(1)
Yeah that make sense as there are two ways to initialise a variable (or constant) in swift. 1. default values (which you have done here) or 2. initialise using a init methodConnor

© 2022 - 2024 — McMap. All rights reserved.