how to apply binary operands on optionals in ios swifts
The Swift programming linguistic communication brings a number of new features that make developing apps quicker, easier and safer than e'er before. One of these new features is Optionals. They're everywhere in Swift but tin can be confusing for people who are new to the language and frustrating to others who don't understand them fully. The primary goal for his article then, is to bring some low-cal to this potentially confusing world by taking a deep-dive into Optionals.
What Problem Do Optionals Solve?
We'll start by first looking at the problems optionals are trying to solve.
The problem of dealing with non-existent values in code has existed since the dawn of computing. In an ideal globe, our lawmaking would always works with consummate and well-defined data but this tin't always exist the case. In many programming languages, programmers resort to using special values in these situations, values that they use to try and represent the absence of a value. I commonly used instance of this is nil which is frequently used to correspond no value at all. At that place are notwithstanding, bug with this.
In most programming languages nothing can but be used to represent the absence of reference types and mostly they don't back up using nil to stand for the absence of value types. The result then is that for value types, developers still have to invent their own encodings to represent no value at all.
On acme of this, although developers are able to come up with these special encodings, there is null built into virtually languages to communicate when the encodings may or may not be used. At that place is generally nothing in the declaration of functions or methods that highlights whether a nil value volition exist accepted and similarly nothing to betoken whether those functions or methods can render a zilch value either.
In many cases, the only identify for this blazon of information is the documentation. Many times though, the documentation either isn't available or simply isn't complete. The result is that nosotros're often left guessing about exactly how to use a particular office or method and this inevitably leads to mistakes and the introduction of hard to find bugs.
With Swift, things are different. Swift attempts to tackle these problems head-on by baking special syntax straight into the language to bargain with the absence of values. This comes in the form of Optionals.
What Are Optionals?
In Swift, an optional type is a type that is used to point the potential absence of a value.
Optionals indicate a combination of two things. They indicate that if there is a value the value will be of a specified type whilst simultaneously indicating that equally there may exist no value at all. In similar fashion to other languages, Swift uses nil to correspond the situation where at that place is no value at all.
Past incorporating optional types straight into the language, Swift forces the states to be clear about whether a particular variable, abiding, parameter or return value tin exist nix and does so correct there in the code rather than forcing united states of america to rely on the documentation for that sort of information.
If a type of a parameter or return value is marked as being an optional type, a value may exist naught. If not, then nosotros tin can be 100% sure that the return value will never be aught and the compiler will actually enforce this fact.
At that place are a number of advantages to this.
Firstly, it saves a lot of mental baggage when reading Swift code and significantly reduces our reliance on the documentation.
Secondly, by forcing us to call back near and deal with the potential for nix values whilst we're writing the lawmaking it helps eliminate issues that may take previously but surfaced at run-time.
Finally, past being explicit nearly when values may or may non be cypher, we can also have the compiler perform a number of checks on our behalf. This last one is a huge advantage.
Whether we like information technology or not, our human brains have a limited capacity for thinking through the multitude of paths through our lawmaking. In many cases, identifying all the paths and associated edge cases can be extremely difficult. Add into that the job of identifying which of them may issue in a value existence nil and it becomes almost impossible. The compiler all the same, is much ameliorate at this than we are and tin help place and check for these edge cases, looking for any nix values that we may have missed. In doing and so information technology prevents a whole class of runtime issues from e'er occurring.
And so, we've looked at what optionals are and nosotros've looked at some of the advantages of having them baked into the language, but how practice we really declare them? Permit'southward take a look at that next.
Declaring Optional Types
In Swift, we declare an optional blazon by adding a question mark character (?) to the end of a normal type. We can do this for any type of value in Swift, whether it be reference type or value type.
For example, say I wanted to declare an optional integer value, I would normally signal this by declaring the abiding or variable to exist of type Int. If instead I wanted to declare the abiding or variable to be an optional though, I would add a ? after the blazon to declare the constant or variable to exist of a new optional integer type:
var optionalInt : Int? The code above declares the optionalInt variable to be of type Int? which indicates that it may contain a value of type Int but in certain circumstances may contain nil.
Now, there is one thing I should indicate out at this betoken. Optional types are Non the same type as their not-optional counterparts. We can come across this if nosotros endeavor to run the following lawmaking:
a : Int = ane b : Int? = 2 a + b // displays the following error: // "Value of optional type 'Int?' non unwrapped: did y'all mean to use '!' or '?'?" From the compilers perspective the optional type and its non-optional counterpart are ii singled-out types and cannot be used together in the same expression. If y'all think virtually it it's actually logical. It doesn't really make sense to attempt to add an integer value to something that may or may not contain some other integer value.
In essence, nosotros can think of an optional as a box which may or may non contain a value of the type we specify. In order to use the value in that box we must first open information technology up and check whether a value is actually nowadays. In Swift, this box-opening process is called unwrapping and there are iii major ways we can achieve information technology.
Unwrapping Optionals
Forced Unwrapping
The first way to unwrap an optional in Swift is something called force unwrapping. Forced unwrapping uses the strength unwrapping operator and we write it every bit an exclamation marker (!) direct later on the proper noun of the optional constant or variable.
The assertion mark tells the compiler to unwrap the value in the optional and to use information technology. No if's, no buts, no checking. Essentially it turns off all the normal checks that the compiler would perform to ensure that the box actually contained a value and instead moves that responsibility to you as the programmer. With this responsibility so comes some associated risk.
A lot of the time, nosotros don't really know whether an optional contains a value or non and if we use the forced unwrapping operator and it turns out that the optional doesn't contain a value, nosotros tin inadvertently trigger a runtime exception which volition crash our app.
If nosotros want to use this forced unwrapping operator then, information technology's prudent to start check that the optional contains a value before nosotros force unwrap information technology. The simplest way of doing this is past using an if statement:
var c : Int = 3 var d : Int? = 4 var result : Int if (d != null) { event = c + d! } As you might look though, performing these checks in Swift is pretty common and writing if statements everywhere isn't ideal so Swift provides usa with an culling syntax that pretty much eliminates the need to use forced unwrapping. This is something called optional bounden.
Optional Binding
Optional bounden is the 2nd way to unwrap optionals in Swift and has syntax is built directly into the language to support it.
Optional binding allows u.s. to bank check an optional and excerpt its value (if information technology exists) into a temporary constant or variable all in a single line of code. Support for this is provided in both the if and while statements in Swift. Let's look at an example:
if let e = d { // Inside the if statement 'e' contains the unwrapped value // from the optional `d` if it is non zero. result = c + e } Every bit you can see, the syntax for optional binding is relatively simple.
We use the if argument followed past the var or permit keywords (depending on whether we want to declare a temporary variable or constant), followed by the assignment operator and and so the name of the optional we want to check.
In uncomplicated terms, the code can be read equally: "If the optional d contains a value, set a new abiding called e to the value contained within that optional".
If the optional contains a value (which we check using the if statement), the temporary constant e is then available as a local constant inside the body of the if statement eliminating the need for united states of america to force unwrap the value held in d. This completely removes the need to use the force unwrapping operator within the body of the if statement.
Shadowing
It might seem foreign, simply when unwrapping an optional in this fashion, we tin can as well unwrap the optional into a new temporary abiding with the exactly same name as the original optional:
if let d = d { // Inside the if statement `d` contains the unwrapped value // from the original optional `d` if it is non nil. result = c + d } This is an example of something chosen shadowing and the effect is to create, in this instance, a new temporary constant called d that is bachelor inside the inner scope of the if statement that hides or shadows the variable d in the outer telescopic.
You lot can run across this if you check the types of the values. d in the outer telescopic is of type Int? (an optional) whilst d in the inner telescopic is of type Int (a normal value type). Past using shadowing it means you lot don't take to utilise explicit unwrapping to exist able to use the value held in d inside the inner telescopic.
At that place are pluses and minuses to this arroyo though.
Some people like it every bit it means that they don't have to call up of or remember, a new variable proper name for the unwrapped value.
Others, still, dislike the approach as they believe that the unwrapped version should have a different name from the original (mainly to highlight the fact that the optional has been unwrapped).
When it boils downwards to information technology, there is no right or incorrect answer to this though. My preference is to employ a different variable or constant name every bit I recall it makes things clearer only the pick is a purely stylistic 1 and i that you will have to choose for yourself.
Now before nosotros wrap upward optional binding, there is a couple of other examples I want to prove yous.
Bounden Multiple Optionals on a Single Line
When Swift first came out, we could only perform optional binding upon a single optional at a time. This used to lead to something similar to the post-obit (frequently nicknamed the pyramid of doom) where, as the number of optionals nosotros wanted to bind increased, nosotros got ever increasing levels of nested if statements:
var k : Int? = iv var l: Int? = 8 if let chiliad = chiliad { if let north = l { // Do something with grand and n } else { print("l contained nil") } } else { impress("grand contained nil") } Swift 1.2 however, introduced the power to bind multiple optionals on a single line. This helped the states write lawmaking in a more than compact form with the beginning branch of the if statement simply being executed if ALL of the optional bindings were successful:
if permit grand = k, north = l { print(m + n) } else { print("k or l contained nil") } // prints "12" We also accept the ability to combine one or more bindings with an optional boolean expression using a where clause. Once more, all on a single line. In this case, the binding only takes place if all the optional(south) contain a value and the where clause evaluates to truthful:
var o : Int? = 4 if let p = o where o > 2 { print(p) } // prints "4" Implicitly Unwrapped Optionals
If you start using optionals for any length of time, you'll soon notice the additional layer of syntax that is associated with them, a layer of syntax that can often brand our code more difficult to read. In certain specific cases though, cases where nosotros know that our optionals will contain a non-goose egg value, Swift allows us to dispense with the additional optionals syntax and allows us to use optionals just like any other constant or variable. To practice this though nosotros accept to mark our optionals as being implicitly unwrapped, the third mechanism past which we can unwrap optionals in Swift.
Implicitly unwrapped optionals are a flake of a foreign beast. On the one hand, they acquit similar optionals (in that they can be set to zip and we tin cheque them for nil equality) but on the other hand, the compiler volition automatically unwrap them every time they are accessed which allows us to dispense with all the optional syntax we've been using up until at present.
To marker an optional every bit being an implicitly unwrapped (rather than a plain old optional) nosotros employ an assertion mark (!) afterward the blazon instead of a question mark (?). You can see this in the example below:
// Without Implicit Unwrapping let possibleInt : Int? = four let forcedInt: Int = possibleInt! // With Implicit Unwrapping let assumedInt : Int! = four allow implicitInt = assumedInt Equally yous can see, past marking the assumedInt variable equally being implicitly unwrapped, we no longer demand to utilise the forced unwrapping operator that we used in the first part of the instance. Instead, we tin simply access the variable as if information technology were a non-optional type.
At that place is a catch though.
By mark an optional equally existence implicitly unwrapped, nosotros are making a promise to the compiler that when the optional is accessed, the optional volition e'er contain a non-nil value.
In like fashion to the forced unwrap operator we saw earlier, if we break this promise (and the implicitly unwrapped optional doesn't contain a value when accessed), Swift will trigger a runtime error and crash our awarding:
var greeting: Cord! = "how-do-you-do world" greeting.capitalizedString // Returns "Hullo World" greeting = nix // As it'due south an optional we can set its value to cipher greeting.capitalizedString // CRASH! - Can't ship letters to nil! With this in heed then, implicitly unwrapped optionals come with all the aforementioned caveats equally forced unwrapping.
We should merely ever marker an optional as being implicitly unwrapped if nosotros are 100% sure that information technology volition NOT exist zilch at the time it is accessed and if there is whatsoever uncertainty nosotros should either apply a not-optional value (if we tin) or a normal optional value if need exist.
In general, implicitly unwrapped optionals are pretty unsafe beasts and run a high chance of causing runtime exceptions only with that said, there are a couple of specific situations in Swift where using them is essential. Let'south have a look at a these side by side.
Using Implicitly Unwrapped Optionals During Initialisation
When it comes to the initialisation of classes in Swift, in that location are some pretty strict rules. One of these rules (and I quote directly from the Swift two.0 Programming Language Guide) is the fact that:
Classes and structures must set up all of their stored properties to an advisable initial value past the time an example of that form or construction is created. Stored properties cannot exist left in an indeterminate state.
In reality, e'er satisfying this statement is pretty tricky. There are a number of reasons for this.
Sometimes we don't have enough information at the time nosotros're creating a class or struct to provide a sensible set of initial values. Sometimes it just doesn't make sense to initialise the properties at that fourth dimension. Any the reason, it is non uncommon to want to exit the initialisation phase of a class or struct without having fully initialised the class. UIViewControllers are ane example of this.
In the case of a UIViewController (and many other view-based classes for that matter), initialisation is separated into two distinct phases.
In the start phase, the case of the UIViewController class is created and initial values are assigned to the unlike properties of the instance (usually via some variant of their init functions). The problem though is that at that point, the IBOutlets for that class will non accept been connected because the views for the class accept not been loaded. This leaves the class partially initialised at the stop of the init function.
It is non until the second phase of the initialisation that the views for the class are loaded. At this point the view and any of the sub-views created within the loadView or viewDidLoad methods are added to the view hierarchy and the IBOutlets are hooked upwards before being presented on screen. The key betoken to note here though is that this is done after the main initialisation of the grade is complete.
The problem so is how to satisfy Swift'due south requirements that all the stored properties of the form have appropriate initial values by the end of initialisation fifty-fifty though we can't yet connect the views and IBOutlets. This is where implicitly unwrapped optionals come up in.
Past defining our IBOutlet backdrop as beingness implicitly unwrapped, were are able to satisfy Swift's requirements. This is because as optionals they are, by default, assigned an initial value of cipher and are therefore deemed to be initialised in the eyes of the Swift compiler.
The advantage of marking them as implicitly unwrapped optionals (rather than being simple optionals), is that one time hooked up, the backdrop can still be referred to like normal non-optional properties instead of having to use the additional optional syntax we already seen:
var characterization : UILabel! //... label.text = "Howdy World" As you lot tin can see, it'south a pretty specific case, but works quite nicely with implicitly unwrapped optionals.
Using Implicitly Unwrapped Optionals With Failable Initializers
A second, like example of using implicitly unwrapped optionals in Swift is using them inside failable initialisers.
When writing Swift code, information technology can sometimes be useful to define a class, structure or enumeration for which initialisation can neglect. There could be whatsoever number of reasons for this. Incorrect or missing initialisation parameters, the absence of some external resources or one of a whole host of other reasons.
To cope with these situations, Swift allows us to ascertain one or more failable initializers as function of a structure, class or enumeration definition. These failable initialisers are failable considering they may either return an initialised object of the specified type or they can fail and render nil instead.
To mark an intializer every bit failable, we add a ? afterward the init keyword but before the method parentheses:
// This WON'T compile!! class PersonClass { allow name : String init?(name: Cord) { if name.isEmpty { return nil } self.proper noun = name } } // Returns the error: All stored properties of a course must be // initialized before returning nil from an initializer. As you tin see though, in this example we have an event. It won't compile.
In this example, I'm declaring a grade that has a failable init method and in this case, intialization will neglect if the name that is passed into the initialiser is an empty String.
At present, the full general rule within failable initialisers is to return nil as soon as an error is encountered. By definition though, this means that not all properties within the object may have been initialized past the time the initialiser returns. Swift has picked up on this fact and every bit a result won't compile our lawmaking as information technology contravenes the 'all properties must exist initialised rule'.
As we've just discussed though, implicitly unwrapped optionals permit us to ascertain a property to take an initial value of nil when a valid value cannot yet be assigned and yet even so allow us to access those values without all baggage of additional optional syntax. Nosotros can make utilise of this fact with failable initialisers.
In this example then if we change the proper name belongings from being a normal String type to being an implicitly unwrapped optional, nosotros can satisfy Swifts requirements and also yet admission the backdrop with normal property syntax:
class PersonClass { var name : String! init?(name: String) { if name.isEmpty { return nil } self.proper noun = name } } As a side note, in order to brand this piece of work in Swift 2.0, nosotros also have to change the name property from being a constant to being a variable.
This is due to a loophole in earlier versions of Swift that could event in constant properties being assigned values multiple times within an initialiser. Apple has since closed this loophole but as a result, nosotros now have to use a variable in this situation rather than a abiding. As tin can be seen from this forum thread Chris Lattner's view is that this a brusk-coming in the language, so it may even so be fixed in future Swift versions just for now, just keep this in mind.
Anyhow, I'm going to leave implicitly unwrapped optionals at that place for now. There's a lot to them and a lot to get your head effectually but merely endeavor to recall that they are designed for some pretty specific use cases in Swift and in those situations their cracking, but beyond those specific scenarios they (like strength unwrapping) run a loftier-risk of runtime errors so use them with care.
So with implicitly unwrapped optionals put to bed, allow'due south wrap things up for today with a wait at the nil coalescing operator, a new operator in Swift that tin can be especially useful when used in conjunction with optionals.
The zero Coalescing Operator
Sometimes when an optional has no value, you desire to provide a default one. We could obviously do this with an if statement or employ the ternary operator:
let optionalValue = myFunc() // May return `nil` seven + (optionalValue != cypher ? optionalValue! : 0)
Note: In this case, the question mark is non used to indicate an optional type, it is part of the syntax for a ternary operator.
If y'all're not familiar with the ternary operator, the second line of code in the example essentially says: "If optionalValue has a value, use information technology, otherwise employ 0".
With the zippo coalescing operators, we can improve on this though.
The null coalescing operator is written every bit a double question marker (??) and is a way of shortening the expression higher up. It has a syntax like to the ternary operator but allows us to manipulate with the check for goose egg:
vii + (optionalValue ?? 0) All information technology does is render the unwrapped optional value if the optional contains a value or the value afterwards the operator if the optional is nil. It's a convenience more than anything else but does make our code slightly easier to read.
Anyway, I'm going to leave it there for today. As always, if you accept any questions, observations, or if I've got anything incorrect, then delight get in touch on.
Source: https://andybargh.com/optionals-in-swift/
Posted by: roushblit1936.blogspot.com

0 Response to "how to apply binary operands on optionals in ios swifts"
Post a Comment