Swift's optional is not Objective-c nil

皆さんこんにちは！
My Japanese writing skill is limited so I will keep posting in English ^_^.


There are a few articles on Qiita that cover the basic usage of swift's optional type,in case you haven't checked them out:
[[Swift] Swiftのoptional valueの便利さ /「?」と「!」でより堅牢なコードへ](http://qiita.com/nori0620/items/afa94cc42f3233f54bdc "Swift")
[Swiftの「?」とか「!」などのOptional Valueの挙動を調べてみた](http://qiita.com/yuichiroharai/items/7e2b8b0922f76c5c5cad "swift")
[SwiftのOptionalとType Safety](http://qiita.com/mo_to_44/items/f9b2678d22ad06599308 "swift")

In this post I want to go a bit further, to explain what optionals really are, and how things work behind the curtain. Since confusing swift's optional type with objective-c's nil type is what trips most people over, I will start here. In addition, I will show you how to use **optional chaining** and **optional binding**.

Definition: **an Optional is a constant or variable in swift that can or cannot be nil.**

```swift:optionals.swift
var strValue: String?  //is equal to the following:
var strValue: Optional<String> 
```
the ? is a syntactic sugar for declaring an optional ***value type***, which means when you write something like **String?** you are **not** declaring a **String** which might be optional, but an **Optional** which could hold a **Sting**, or nil.

“Swift’s nil is not the same as nil in Objective-C. In Objective-C, nil is a pointer to a non-existent object. In Swift, nil is not a pointer—it is the absence of a value of a certain type. Optionals of any type can be set to nil, not just object types.” - [***The Swift Programming Language***](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/ "swift programming language").

First of all, all value types in swift must be initialized before usage, with a default value. So there's no such thing as "a string that might be empty". Second, optional values cannot be used directly, it must be unwrapped(that's where the !, optional chaining and optional binding comes in handy, I will explain later). 

I've seen some posts uses Optionals this way:

```swift:optionals.swift
var optional:String?
var mustBeThere = optional! 
```
Hmmm...not exactly a good idea when you cannot be sure whether the optional holds a value. Be really careful with the ‘!’ operator (which unwraps the optional and exposes the underlying value). Because if the optional is nil, this produces a runtime error.

If you are still confused, let's see what optionals really are, here is its implementation you can find in Xcode6:

```swift:optionals.swift
enum Optional<T> : LogicValue, Reflectable {
    case None
    case Some(T)
    init()
    init(_ some: T)

    /// Allow use in a Boolean context.
    func getLogicValue() -> Bool

    /// Haskell's fmap, which was mis-named
    func map<U>(f: (T) -> U) -> U?
    func getMirror() -> Mirror
}
```
Aha! it's an enum! To be more specific, it's an enum with two options: **.Some** which chould be the value type it holds, and **.None**(which is nil).

So let's read this again:

```swift:optionals.swift
let optionalTen: Int? = 10
```
An optional declaration doesn’t say “this is an Int, which is optional”. It says, “this is an Optional, which may or may not hold an Int”.
In fact, opitonals, are values types, just like Int, String, Array...you get the idea. In Objective-C, nil values are acceptable, therefore when you bridge Objective-C code with Swift code, all Objective-C types will be returned as Optional.

Unwrapping rule: you can’t use the value of a variable with an optional type directly.

```swift:optionals.swift
class Person {
  var name: String
  init(_ name: String) {
    self.name = name
  }
}
var p: Person? = Person("John")  // p is optional/nil-able
var greeting = "Hello" + p.name // Compile-time error
var greeting = "Hello" + p!.name // “Hello John”
```

The ‘!’ operator unwraps the optional and exposes the underlying value (in this case the string "John"). If p is nil, this produces a runtime error.

remember how we check whether a value is nil in ObjC?

```objectivec:file.m
if (!testVar) {
    NSLog(@"testVar is nil");
} else { 
    NSLog(@"testVar is equal to %@", testVar);
}
```

in Swift: use ***optional binding*** — if let

```swift:optionals.swift
var testVar: String? = myRandomFunction() /*May return nil*/
if let constVar = testVar { 
 println("testVar is equal to \(constVar)")
} else { 
 println("testVar is equal to nil")
}
```
It’s safer and preferable to use “optional binding” to unwrap an optional.

try one from Objective-C API:

```swift:optionals.swift
let formatter = NSDateFormatter()
let now = formatter.dateFromString("not_valid")
let soon = now.dateByAddingTimeInterval(5.0) /*Runtime error.*/
/*In the equivalent Objective-C code, ‘soon’ would be nil, rather than producing a runtime error. */

/*nil check use if statement:*/
if let soon = now.dateByAddingTimeInterval(5.0) {
  // soon is a concrete NSDate
} else {
  // soon is nil
}

```

Optional Chaining — use ?. to chain multiple optionals together and conditionally check if each value in the chain exists.

```swift:optionals.swift
var testVar = varOne?.varTwo?.varThree
if let varOne = optionalFuncOne() { 
    if let varTwo = optionalFuncTwo() { 
        if let varThree = optionalFuncThree() { 
            testVar = varThree
        }
    }
}
```
Syntactic sugar again, under the hood you can understand it as nested optional bindings.

-----------

Now, with your newly developed skill, let's take a look at this function from WWDC session 404:

```swift:file.swift
func stateFromPlist(list: Dictionary<String, AnyObject>) -> State? {
  switch (list["name"], list["population"], list["abbr"]) {
      case (.Some(let listName as NSString),
      .Some(let pop as NSNumber),
      .Some(let abbr as NSString))
      where abbr.length == 2:
          return State(name: listName, population: pop, abbr: abbr)
      default:
          return nil
  }
}
```
Get it? Can you see where the ***.Some*** came from?

I hope you enjoyed Swift so far, optionals are really cool safety features.