Swift Optionals - Inconsistency?

Woodstock

I'm slightly confused - I thought I understood Optionals and on the Apple dev forums Chris L, mentioned a work around to the immutable Optional issue was to create a class wrapper for the optional value type. -link!

However take this example with UIWindow (an optional class type with various properties)

The properties still don't seem mutable with optional chaining!

var window: UIWindow?

//this works (force unwrap)
self.window!.backgroundColor = UIColor.greenColor()


//this optional chain doesn't work... why not? Isn't this just a safer version of the above?
self.window?.backgroundColor = UIColor.redColor()

This seems to be fixed in beta 5!

holex

update for Xcode beta 5


the originally asked issue has been resolved in Xcode beta5, that may invalidate this answer.


original anwer


that may request further explanation, why it is definitely not inconsistent behaviour but is simple invalid.

the optional value has to be always of the right side of the actual operand, and it cannot be on the left side of it.

see that logic via two simple examples:

example 1

in case of this line of code:

self.window?.backgroundColor = UIColor.redColor()
                      < LEFT ^ RIGHT >

the optional is on the left side which would mean the left side could be nil therefore the following operand would appear here in runtime:

nil = UIColor.redColor()

which is clearly invalid on every level without any further or complex explanation – a nil cannot be assigned to something else, that is why the compiler does not allow it.

NOTE: you may assume that the logical behaviour would be like this in the case of self.window = nil:

nil.backgroundColor = UIColor.redColor()

but the documentation about Optional Chaining highlights a very important behaviour which explains why that is not happening at all:

Multiple queries can be chained together, and the entire chain fails gracefully if any link in the chain is nil.

emphasis is on the word "entire", thus that is why the left side will be nil = ... and not nil.backgroundColor = ... as you'd expect after Objective-C.

example 2

the other answer highligths another idea of how it can be solved:

self.window?.setBackgroundColor(UIColor.redColor())

why is that working? would it not be a little inconsistency here? definitely not.

the actual optional is on the right side of the operand here, because that line is equal to this line, however we are not bothered to get the void in practice at all.

let result: Void! = self.window?.setBackgroundColor(UIColor.redColor())
           < LEFT ^ RIGHT >

as you see there is not any inconsistency at all here, because in the case of self.window = nil that line would be equal to this one in runtime (please see the explanation above):

let result: Void! = nil

and that would be a completely legal operand.

the logic is simple, the optional must be always at the right side of the operand (or operator), on the left side it can be non-optional value only.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related