Strange behaviour using let and var kindly guide

Hi,

I am just learning from swift documentation and other online free material , and I might be asking some thing really simple but I have been trying to solve this for few hours rereading the documentation but have not found a solution to this, I read about let and var as well but do not have any solution ... so please pardon my ignorance ...

I have the below code

var myString: String?


if let myString1 = myString {
    print("Your string has - \(myString1)")
} else {
    print("Your string does not have a value")
}

Now my query is that if I use

var myString: String?

myString become nil in playground and code gives output as

Your string does not have a value

But if I change it to let

let myString: String?

I get error that - Constant 'myString' used before being initialized

please guide ....

Amit

When you declare an optional, the compiler will initialize it for you, if you don't assign a value at the same time.

var a: String? = "a"
var b: String?

The first will have the value assigned ("a"), while the second is assigned 'nil'.

[edited for correctness]

However, let vars can't be reassigned. Because of this, the compiler makes no assumptions, nor will it implicitly assign a value for you. Instead, you get an error.

@Avi thanks but the below code works with let as nil

let myString: String? = nil


if let myString1 = myString {
    print("Your string has - \(myString1)")
} else {
    print("Your string does not have a value")
}

It gives output - Your string does not have a value

please guide

In this case, you've given it an initial value. I misspoke when I wrote earlier that the let variable can't be nil. What I should have written is that, because the value can't be changed, the compiler makes no assumptions on your behalf. You can assign nil to an optional let var, but it will never be implicitly assigned that value.

@Avi - but that was bit confusing if the compiler makes no assumption what exactly does - let myString: String? hold, the absence of no value is considered to become nil if using optional so why not in this case ?

It holds nothing until assigned a value. As the error informs you, you can't do anything with it until you've assigned one.

It's a bit like declaring intent. You are telling the compiler that a value of that type should exist in the declared scope. But you don't actually have a usable variable until you give it a value. The compiler allows this for reasons such as the following code:

let maybe: String?
if someVar == true {
    maybe = "certainly"
else {
    maybe = nil
}

The compiler knows that the variable will definitely have a value after the if statement, so you don't need to assign one at the declaration site. And, because it's declared at the same level as the if, it's still in scope after the if.

The same rules hold for instance variables which are initialized in a constructor. The compiler ensures that all instance variables have a value before construction ends.

@Avi, so please tell me if I am thinking the right way -

the compiler allows var to be nil as it can be changes later , but it does not give let that option as it can be initialised just once and the compiler wants the user to do that , and also in future I should be assured of this behaviour every where , right ?

Correct.

1 Like