# Optionals

## Overview

When you assign data to a variable, that data defines the data type. But "**nil**" does not have a data type. Therefore Swift will throw an error.

Every time you create a variable, you must define its type, whether by explicitly defining it

```swift
var name: String
var age: Int
```

or by entering data in it

```swift
var name = "Sedat"
var age = 44
```

But if you neither not define the type nor do not enter data into a variable, swift cannot know the type of the variable.

```swift
var name  // Error: Type annotation missing in pattern
var age  // Error: Type annotation missing in pattern
```

Sometimes you may not want to define its type in advance. In such a situation, it will be empty. So entering "nil" does not solve the problem because it does not have any data type.

```swift
var name = nil // Error: 'nil' requires a contextual type
var age = nil // Error: 'nil' requires a contextual type
```

And sometimes you can define the data type but you don't exactly know which type is it, in such a situation you may think adding a "nil" may solve it, but it does not

```swift
var name: String = nil // Error: 'nil' cannot initialize specified type 'String'
var age: Int = nil // Error: 'nil' cannot initialize specified type 'String'
```

But adding an optional sign "?" to the type may solve the problem

```swift
var name: String? = nil
var age: Int? = nil
```

### Unwrapping the Variable

### Nil-Coalescing

```swift
// if the result is "nil", prints "Anonymous"
struct Book {
    let title: String
    let author: String?
}

let book = Book(title: "Beowulf", author: nil)
let author = book.author ?? "Anonymous"
print(author)sw

// print: Anonymous
```

```swift
// if the result is "nil", prints "0"
let input = ""
let number = Int(input) ?? 0
print(number)

// print: 0
```

```swift
// Multiple criteria
let savedData = first() ?? second() ?? ""
```

### Optional Binding

### Optional Chaining

```swift
let names1 = ["Arya", "Bran", "Robb", "Sansa"]
let names2 = [String]()

let chosen1 = names1.randomElement()?.uppercased() ?? "No one"
print("Next in line: \(chosen1)")
// print: BRAN

let chosen2 = names2.randomElement()?.uppercased() ?? "No one"
print("Next in line: \(chosen2)")
// print: No one
```

```swift
struct Book {
    let title: String
    let author: String?
}

var book: Book? = nil
let author = book?.author?.first?.uppercased() ?? "A"
print(author)

// print: A
```

**Source:** [HWS](https://www.hackingwithswift.com/quick-start/beginners/how-to-handle-multiple-optionals-using-optional-chaining)

## Sources

### Videos

{% embed url="<https://www.youtube.com/watch?v=IG_JCxSPa_k>" %}

### Articles / Documents

* [Hacking with Swift / 100 days / 14 - Optionals](https://www.hackingwithswift.com/100/swiftui/14)
