WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

SOLVED: Question: Aren't all data optionals ?

Forums > 100 Days of SwiftUI

The way Optional described makes me think that aren't all data optionals ?

In the end , who can always been 100% sure the specific piece of data we are trying to access is there ?

Right ?

Then, do we need to always mark data with ? or using default value or using nil-coalescing ?

Thank you in advance,

Boat

   

When you create an optional value by using Int?, Date?, String?,... you're saying the data may or may not be there.

When you create a value by saying Int, Date, String,... you're saying it has to contain something. So by creating a non-optional value you're saying it absolutely has to have something in there or your program is not going to compile. You create it as non-optional and you assign it something, so you're 100% sure it's there.

Optionals are when the data might not be there, i.e. trying to get data from a server, a file, or some other stored data may result in no data coming back, or performing a method on an empty array that hasn't been filled yet, or any instance where the data simply may not exist.

let yourBirthday: Date? = nil
let myBirthday = Date.now
print(yourBirthday)
print(myBirthday)
// Prints - nil
// Prints - 2022-02-06 13:22:01 +0000

var w: Int?
print(w)
// Prints - nil

var x: Int
print(x)
// Shows warning - Variable 'x' used before being initialized
// - Crashes playground
// - Main.xcplaygroundpage:14:5: note: variable defined here

var y = 5
y = nil
// Prints - error: Main.xcplaygroundpage:7:5: error: 'nil' cannot be assigned to type 'Int'
print(y ?? "7")
// Shows warning - Left side of nil coalescing operator '??' has non-optional type 'Any', 
// so the right side is never used
// Prints - 5

Another example:

let yourBirthday: Date?
// - I don't know your birthday so I'm going to make it optional instead of filling 
// in a random value that makes no sense
// - Hold down the option key, click on yourBirthday and you'll see it's optional

yourBirthday = Date.now
// - Hold down the option key, click on yourBirthday and you'll see it is still optional, 
// even though we've given it a value

let nonOptionalBirthday = yourBirthday ?? Date.now
// nonOptionalBirthday is non-optional Date type because by nil coalescing 
// we've said it has to contain something so Swift uses type inference to create
// it as a Date type. If yourBirthday contains nil then it gets assigned Date.now. 
// If it's not nil then it gets assigned whatever value was in yourBirthday.

1      

Vince has the right answer! Here are additional examples.

Example

Get a box and write "Boat's Height" on it. Make a declaration that only Integers can go into the box. Now try and put the box on your desk. Your desk will complain that you cannot put the box on the desk until you put a value in the box. (You must initialize it.)

Once you initialize the box with a value and you declared the box as a var, you can change the value inside the box, but the box must always have an integer in it.

If you try to take the value out and put nothing in the box (ie give the box a nil value, your desk will complain again.)

var boatsHeight : Int  // Box can only hold Integers
print("Boats' height: \(boatsHeight)") // Swift will complain about this!

boatsHeight = 103  // Must have a value!
print("Boats' height: \(boatsHeight)")  // get the value in the box.

// Try!  Try to put nothing in the box. Swift complains!
boatsHeight = nil // error: 'nil' cannot be assigned to type 'Int'

Ask yourself, what's a good value for boatsHeight if you don't know it?
Zero? A negative one? Any negative number? Using a convention like this will add additional if-else rules to your business logic. Not best practice.

Optional Example

Now make a declaration that the box is optional Integer. You can put the box on your desk with or without a value in it. If a friend calls you up and asks "What's the value in the box?" You can have a look and report back the box is empty! Or you can tell them there's an integer in the box, and give them the value.

To use the value, you first must determine if you HAVE A VALUE IN THE BOX. If the box has a value, then you can use it.

// Paste into Playgrounds
var boatsHeight : Int? = 103

boatsHeight // Ask playgrounds to tell you what's in the box.

// You always have this box on your desk.
// But, it might not have anything inside it.
boatsHeight = nil // Put nothing in the box
let height = boatsHeight == nil ?  "unknown" : "\(boatsHeight)"  // check first before using
print("Boat's height is: \(height)")

What if you don't know a person's height?
You could set height to 0, or to a negative number. But in your program, you'll have to deal with this extra business rule. Avoid that issue by using an optional when ever you may or may NOT know the value.

boatsHeight = 105  // Now the box has a value.
if let height = boatsHeight { // Still, please check to see if it has a value.
    print("Boat’s height is: \(height)" )
}

1      

HI Vince, @vtabmow

you said:

When you create a value by saying Int, Date, String,... you're saying it has to contain something. So by creating a non-optional value you're saying it absolutely has to have something in there or your program is not going to compile. You create it as non-optional and you assign it something, so you're 100% sure it's there.

can I understand it that:

By creating an non-optional value , I tell Swift that "Don't compile if there is not value , because it is supposed to have a value for sure"

By creating an optional value, I tell Swift that "You may still compile if there is no value, because I am telling you so. "

Is my understanding above correct ?

Boat

   

Almost.

If you declare a non-optional value the compiler don't let you compile your program if there is no value before accessing it the first time.

On the other hand, if you declare an optional value the compiler makes sure you unwrap the value before accessing it (either with if let, guard or !)

So in both cases the compiler helps you to avoid a fatal error at runtime.

1      

Thank you @Hatsushira

Have a nice day

Boat

   

Hacking with Swift is sponsored by Emerge

SPONSORED Optimize your app’s startup time, binary size, and overall performance using Emerge’s advanced app optimization and monitoring tools. Reliably measure app size, speed up your app's startup time with Emerge's Launch Booster, and much more. Emerge is actively used by many of the top mobile development teams in the world.

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.