[swift] What is an optional value in Swift?

From Apple's documentation:

You can use if and let together to work with values that might be missing. These values are represented as optionals. An optional value either contains a value or contains nil to indicate that the value is missing. Write a question mark (?) after the type of a value to mark the value as optional.

Why would you want to use an optional value?

This question is related to swift optional

The answer is


Here is an equivalent optional declaration in Swift:

var middleName: String?

This declaration creates a variable named middleName of type String. The question mark (?) after the String variable type indicates that the middleName variable can contain a value that can either be a String or nil. Anyone looking at this code immediately knows that middleName can be nil. It's self-documenting!

If you don't specify an initial value for an optional constant or variable (as shown above) the value is automatically set to nil for you. If you prefer, you can explicitly set the initial value to nil:

var middleName: String? = nil

for more detail for optional read below link

http://www.iphonelife.com/blog/31369/swift-101-working-swifts-new-optional-values


An optional means that Swift is not entirely sure if the value corresponds to the type: for example, Int? means that Swift is not entirely sure whether the number is an Int.

To remove it, there are three methods you could employ.

1) If you are absolutely sure of the type, you can use an exclamation mark to force unwrap it, like this:

// Here is an optional variable:

var age: Int?

// Here is how you would force unwrap it:

var unwrappedAge = age!

If you do force unwrap an optional and it is equal to nil, you may encounter this crash error:

enter image description here

This is not necessarily safe, so here's a method that might prevent crashing in case you are not certain of the type and value:

Methods 2 and three safeguard against this problem.

2) The Implicitly Unwrapped Optional

 if let unwrappedAge = age {

 // continue in here

 }

Note that the unwrapped type is now Int, rather than Int?.

3) The guard statement

 guard let unwrappedAge = age else { 
   // continue in here
 }

From here, you can go ahead and use the unwrapped variable. Make sure only to force unwrap (with an !), if you are sure of the type of the variable.

Good luck with your project!


Well...

? (Optional) indicates your variable may contain a nil value while ! (unwrapper) indicates your variable must have a memory (or value) when it is used (tried to get a value from it) at runtime.

The main difference is that optional chaining fails gracefully when the optional is nil, whereas forced unwrapping triggers a runtime error when the optional is nil.

To reflect the fact that optional chaining can be called on a nil value, the result of an optional chaining call is always an optional value, even if the property, method, or subscript you are querying returns a nonoptional value. You can use this optional return value to check whether the optional chaining call was successful (the returned optional contains a value), or did not succeed due to a nil value in the chain (the returned optional value is nil).

Specifically, the result of an optional chaining call is of the same type as the expected return value, but wrapped in an optional. A property that normally returns an Int will return an Int? when accessed through optional chaining.

var defaultNil : Int?  // declared variable with default nil value
println(defaultNil) >> nil  

var canBeNil : Int? = 4
println(canBeNil) >> optional(4)

canBeNil = nil
println(canBeNil) >> nil

println(canBeNil!) >> // Here nil optional variable is being unwrapped using ! mark (symbol), that will show runtime error. Because a nil optional is being tried to get value using unwrapper

var canNotBeNil : Int! = 4
print(canNotBeNil) >> 4

var cantBeNil : Int = 4
cantBeNil = nil // can't do this as it's not optional and show a compile time error

Here is basic tutorial in detail, by Apple Developer Committee: Optional Chaining


In objective C variables with no value were equal to 'nil'(it was also possible to use 'nil' values same as 0 and false), hence it was possible to use variables in conditional statements (Variables having values are same as 'TRUE' and those with no values were equal to 'FALSE').

Swift provides type safety by providing 'optional value'. i.e. It prevents errors formed from assigning variables of different types.

So in Swift, only booleans can be provided on conditional statements.

var hw = "Hello World"

Here, even-though 'hw' is a string, it can't be used in an if statement like in objective C.

//This is an error

if hw

 {..}

For that it needs to be created as,

var nhw : String? = "Hello World"

//This is correct

if nhw

 {..}

I made a short answer, that sums up most of the above, to clean the uncertainty that was in my head as a beginner:

Opposed to Objective-C, no variable can contain nil in Swift, so the Optional variable type was added (variables suffixed by "?"):

    var aString = nil //error

The big difference is that the Optional variables don't directly store values (as a normal Obj-C variables would) they contain two states: "has a value" or "has nil":

    var aString: String? = "Hello, World!"
    aString = nil //correct, now it contains the state "has nil"

That being, you can check those variables in different situations:

if let myString = aString? {
     println(myString)
}
else { 
     println("It's nil") // this will print in our case
}

By using the "!" suffix, you can also access the values wrapped in them, only if those exist. (i.e it is not nil):

let aString: String? = "Hello, World!"
// var anotherString: String = aString //error
var anotherString: String = aString!

println(anotherString) //it will print "Hello, World!"

That's why you need to use "?" and "!" and not use all of them by default. (this was my biggest bewilderment)

I also agree with the answer above: Optional type cannot be used as a boolean.


An optional in Swift is a type that can hold either a value or no value. Optionals are written by appending a ? to any type:

var name: String?

You can refer to this link to get knowledge in deep: https://medium.com/@agoiabeladeyemi/optionals-in-swift-2b141f12f870


Let's take the example of an NSError, if there isn't an error being returned you'd want to make it optional to return Nil. There's no point in assigning a value to it if there isn't an error..

var error: NSError? = nil

This also allows you to have a default value. So you can set a method a default value if the function isn't passed anything

func doesntEnterNumber(x: Int? = 5) -> Bool {
    if (x == 5){
        return true
    } else {
        return false
    }
}

From https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html:

Optional chaining is a process for querying and calling properties, methods, and subscripts on an optional that might currently be nil. If the optional contains a value, the property, method, or subscript call succeeds; if the optional is nil, the property, method, or subscript call returns nil. Multiple queries can be chained together, and the entire chain fails gracefully if any link in the chain is nil.

To understand deeper, read the link above.


You can't have a variable that points to nil in Swift — there are no pointers, and no null pointers. But in an API, you often want to be able to indicate either a specific kind of value, or a lack of value — e.g. does my window have a delegate, and if so, who is it? Optionals are Swift's type-safe, memory-safe way to do this.


When i started to learn Swift it was very difficult to realize why optional.

Lets think in this way. Let consider a class Person which has two property name and company.

class Person: NSObject {
    
    var name : String //Person must have a value so its no marked as optional
    var companyName : String? ///Company is optional as a person can be unemployed that is nil value is possible
    
    init(name:String,company:String?) {
        
        self.name = name
        self.companyName = company
        
    }
}

Now lets create few objects of Person

var tom:Person = Person.init(name: "Tom", company: "Apple")//posible
var bob:Person = Person.init(name: "Bob", company:nil) // also Possible because company is marked as optional so we can give Nil

But we can not pass Nil to name

var personWithNoName:Person = Person.init(name: nil, company: nil)

Now Lets talk about why we use optional?. Lets consider a situation where we want to add Inc after company name like apple will be apple Inc. We need to append Inc after company name and print.

print(tom.companyName+" Inc") ///Error saying optional is not unwrapped.
print(tom.companyName!+" Inc") ///Error Gone..we have forcefully unwrap it which is wrong approach..Will look in Next line
print(bob.companyName!+" Inc") ///Crash!!!because bob has no company and nil can be unwrapped.

Now lets study why optional takes into place.

if let companyString:String = bob.companyName{///Compiler safely unwrap company if not nil.If nil,no unwrap.
    
    print(companyString+" Inc") //Will never executed and no crash!!!
}

Lets replace bob with tom

if let companyString:String = tom.companyName{///Compiler safely unwrap company if not nil.If nil,no unwrap.
    
    print(companyString+" Inc") //Will executed and no crash!!!
}

And Congratulation! we have properly deal with optional?

So the realization points are

  1. We will mark a variable as optional if its possible to be nil
  2. If we want to use this variable somewhere in code compiler will remind you that we need to check if we have proper deal with that variable if it contain nil.

Thank you...Happy Coding


Lets Experiment with below code Playground.I Hope will clear idea what is optional and reason of using it.

var sampleString: String? ///Optional, Possible to be nil

sampleString = nil ////perfactly valid as its optional

sampleString = "some value"  //Will hold the value

if let value = sampleString{ /// the sampleString is placed into value with auto force upwraped.

    print(value+value)  ////Sample String merged into Two
}

sampleString = nil // value is nil and the

if let value = sampleString{

    print(value + value)  ///Will Not execute and safe for nil checking
}

//   print(sampleString! + sampleString!)  //this line Will crash as + operator can not add nil

Optional value allows you to show absence of value. Little bit like NULL in SQL or NSNull in Objective-C. I guess this will be an improvement as you can use this even for "primitive" types.

// Reimplement the Swift standard library's optional type
enum OptionalValue<T> {
    case None
    case Some(T)
}
var possibleInteger: OptionalValue<Int> = .None
possibleInteger = .Some(100)”

Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks. https://itun.es/gb/jEUH0.l