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.

akashivskyy
  • 44,342
  • 16
  • 106
  • 116
hdsenevi
  • 953
  • 2
  • 14
  • 27

2 Answers2

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.

akashivskyy
  • 44,342
  • 16
  • 106
  • 116
  • 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?' line – hdsenevi Nov 15 '15 at 12:27
  • No. `let` only requires you to **assign the value once, no more, no less**. When talking about initializers, they require all `let`s to have a value before initialization finishes. Therefore you may do this either via default value, _or_ in the initializer itself. – akashivskyy Nov 15 '15 at 12:31
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
Community
  • 1
  • 1
katleta3000
  • 2,484
  • 1
  • 18
  • 23
  • 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 method – hdsenevi Nov 15 '15 at 12:30