12

My understanding so far : If you define an optional variable without assign any values, the compiler will automatically assign the nil

Code Snippets:

A :

var someOptional : Int? //Change to `let` to trigger error 
var aDefaultValue = 42
var theAnswer = someOptional ?? aDefaultValue

The code snippet above works fine, however, when I changed the variable someOptional to a constant, the compiler yelled an error (Please see the attached figure below)

enter image description here

B :

I then tried the similar codes to down to the problem.

var someOptional : Int?
print(someOptional)

Still, it works fine with variable while failed with the constant type.

enter image description here

Conclusion:

If you define a constant optional you have to assign the nil explicitly if you mean that. Because it looks useless (why do you need a constant option with assigned with nil), if the compiler did that for you automatically it may introduce an error.

Question:

Why does the compiler assume nil for var declared optionals but not for let declared optionals?

pkamb
  • 33,281
  • 23
  • 160
  • 191
SLN
  • 4,772
  • 2
  • 38
  • 79
  • 2
    Possible duplicate of [Why optional constant does not automatically have a default value of nil](http://stackoverflow.com/questions/37400196/why-optional-constant-does-not-automatically-have-a-default-value-of-nil) – Hamish Aug 14 '16 at 12:59
  • 2
    Given that this question and [this other question](http://stackoverflow.com/q/37400196/2792531) were both asked by the same user, and the newer question seems a lot more clear and has a much better answer, I've marked the older one as a duplicate of the newer one, rather than vica versa as your close vote recommends @Hamish – nhgrif Aug 14 '16 at 13:13
  • @Hamish ...... OMG This is the second time I did that. I'm new to the programming. It's just too much stuff to remember, this is actually my third round to study the code from the apple documents. I do apologise for the duplication, I forgot some topics of what I learned from the first two rounds. Maybe I need to search my questions first next time. – SLN Aug 14 '16 at 13:16
  • 2
    If you just [look at your own profile](http://stackoverflow.com/users/3004698/sln?tab=questions) you can find a list of question you've asked. But really, even doing this is unnecessary. Just try searching for answers to questions you think of. It's what the pros do. A little bit of research may have prevented *both* of these questions from being asked in the first place. – nhgrif Aug 14 '16 at 13:21
  • @nhgrif Thanks for your kind suggestion and tips, I was lazy, that's a bad attitude. I will make the search rather than quickly pops the question next time. – SLN Aug 14 '16 at 13:24

1 Answers1

10

Yes it's correct

An optional variable doesn't need to be manually initialized. If you read it before having populated it does contain nil.

From Apple docs

If you define an optional variable without providing a default value, the variable is automatically set to nil for you [...]

On the other hand the compiler does force you to manually initialize an Optional constant (let) before you can read it.

Unlike a variable, the value of a constant cannot be changed once it is set. Attempting to do so is reported as an error when your code is compiled [...]

Why?

A constant can be written only once. It doesn't need to happened on the same line it is initialized but it must happened before your read it.

E.g. this code works fine

let num: Int?
num = 1
print(num)

However if the compiler had put a temporary nil value inside num then the constant would have been wrote twice. Which is against the concept of constant.

let num: Int?
print(num) // nil ??? <- this can't work! 
num = 1
print(num) // 1

Another example

This code snippet works fine

func printArea(width: Int?, height:Int?) {
    let area: Int?
    if let width = width, height = height {
        area = width * height
    } else {
        area = nil
    }
    print(area)
}

Again, if the compiler had put a temporary nil value inside area then...

func printArea(width: Int?, height:Int?) {
    let area: Int?
    print(area) // not possible! area is going to change in a moment
     if let width = width, height = height {
        area = width * height
    } else {
        area = nil
    }
    print(area)
}
Luca Angeletti
  • 58,465
  • 13
  • 121
  • 148