Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift: Testing optionals for nil

People also ask

How do you check if something is nil Swift?

In Swift, if we define a variable to be an optional variable, in that case, this variable can have no value at all. If optional variable is assigned with nil , then this says that there is no value in this variable. To check if this variable is not nil, we can use Swift Inequality Operator != .

When should you use optionals Swift?

Optional types or Optionals in Swift You use optionals in situations where a value may be absent. An optional represents two possibilities: Either there is a value, and you can unwrap the optional to access that value, or there isn't a value at all.

Is nil a value in Swift?

In Swift, nil means the absence of a value. Sending a message to nil results in a fatal error. An optional encapsulates this concept. An optional either has a value or it doesn't.

How can we use optional binding to determine if the variable string is not nil?

It's unwrapped by the optional binding if let statement. You can see optional binding as a unwrapping an optional by using a conditional and a constant. When the conditional evaluates to true, i.e. when the optional is not nil, its value is assigned to the constant.


In Xcode Beta 5, they no longer let you do:

var xyz : NSString?

if xyz {
  // Do something using `xyz`.
}

This produces an error:

does not conform to protocol 'BooleanType.Protocol'

You have to use one of these forms:

if xyz != nil {
   // Do something using `xyz`.
}

if let xy = xyz {
   // Do something using `xy`.
}

To add to the other answers, instead of assigning to a differently named variable inside of an if condition:

var a: Int? = 5

if let b = a {
   // do something
}

you can reuse the same variable name like this:

var a: Int? = 5

if let a = a {
    // do something
}

This might help you avoid running out of creative variable names...

This takes advantage of variable shadowing that is supported in Swift.


One of the most direct ways to use optionals is the following:

Assuming xyz is of optional type, like Int? for example.

if let possXYZ = xyz {
    // do something with possXYZ (the unwrapped value of xyz)
} else {
    // do something now that we know xyz is .None
}

This way you can both test if xyz contains a value and if so, immediately work with that value.

With regards to your compiler error, the type UInt8 is not optional (note no '?') and therefore cannot be converted to nil. Make sure the variable you're working with is an optional before you treat it like one.


Swift 3.0, 4.0

There are mainly two ways of checking optional for nil. Here are examples with comparison between them

1. if let

if let is the most basic way to check optional for nil. Other conditions can be appended to this nil check, separated by comma. The variable must not be nil to move for the next condition. If only nil check is required, remove extra conditions in the following code.

Other than that, if x is not nil, the if closure will be executed and x_val will be available inside. Otherwise the else closure is triggered.

if let x_val = x, x_val > 5 {
    //x_val available on this scope
} else {

}

2. guard let

guard let can do similar things. It's main purpose is to make it logically more reasonable. It's like saying Make sure the variable is not nil, otherwise stop the function. guard let can also do extra condition checking as if let.

The differences are that the unwrapped value will be available on same scope as guard let, as shown in the comment below. This also leads to the point that in else closure, the program has to exit the current scope, by return, break, etc.

guard let x_val = x, x_val > 5 else {
    return
}
//x_val available on this scope

From swift programming guide

If Statements and Forced Unwrapping

You can use an if statement to find out whether an optional contains a value. If an optional does have a value, it evaluates to true; if it has no value at all, it evaluates to false.

So the best way to do this is

// swift > 3
if xyz != nil {}

and if you are using the xyz in if statement.Than you can unwrap xyz in if statement in constant variable .So you do not need to unwrap every place in if statement where xyz is used.

if let yourConstant = xyz {
      //use youtConstant you do not need to unwrap `xyz`
}

This convention is suggested by apple and it will be followed by devlopers.


Although you must still either explicitly compare an optional with nil or use optional binding to additionally extract its value (i.e. optionals are not implicitly converted into Boolean values), it's worth noting that Swift 2 has added the guard statement to help avoid the pyramid of doom when working with multiple optional values.

In other words, your options now include explicitly checking for nil:

if xyz != nil {
    // Do something with xyz
}

Optional binding:

if let xyz = xyz {
    // Do something with xyz
    // (Note that we can reuse the same variable name)
}

And guard statements:

guard let xyz = xyz else {
    // Handle failure and then exit this code block
    // e.g. by calling return, break, continue, or throw
    return
}

// Do something with xyz, which is now guaranteed to be non-nil

Note how ordinary optional binding can lead to greater indentation when there is more than one optional value:

if let abc = abc {
    if let xyz = xyz {
        // Do something with abc and xyz
    }        
}

You can avoid this nesting with guard statements:

guard let abc = abc else {
    // Handle failure and then exit this code block
    return
}

guard let xyz = xyz else {
    // Handle failure and then exit this code block
    return
}

// Do something with abc and xyz