【Swift3.0】Swiftの基礎 #1

# はじめに
Swiftの基礎や、よく使うパターンなどについて
ひたすら纏めていきます。

まずは、基礎から纏めます。

# 前提
以下の開発環境での情報を記載します。
**Xcode 8.3ではありません。**

| Category | Version |
|:-----------:|:------------:|
| Swift | 3.0.2 |
| Xcode | 8.2.1 |

Swiftのバージョンを確認できるコマンド
`/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift --version`
**↑↑ Xcode.appをリネームしている場合は、適宜読み替えてください。**

#01. 変数と定数

### 変数

`var 変数名: 型名 = 初期値`

```swift:Demo-1.swift
// Int型の変数numを宣言し、0で初期化
var num: Int = 0

// 変数numに1000を代入
num = 1000

// String型の変数strを宣言し、"foo"で初期化
var str: String = "foo"

```

### 定数

`let 定数名: 型名 = 定数`

```swift:Demo-2.swift
// Int型の定数height
let height: Int = 180

// String型の定数name
let name: String = "okuderap"
```

ちなみに、varはVariableのことらしいです。
letは、Letをそのまま。

# 02. 型推論
明示的に型を宣言せず、代入された値から型を判別してくれるやつのことです。

```swift:Demo-3.swift
// String型
let str = "foo"

// Int型
var intVal = 10

// Double型
var doubleVal = 123.4
```

型推論可能な場合は、基本的に型推論を利用する方向でいきたいと思います。

# 03. Optional Type (オプショナル型)
Swiftの通常の型は**nilを使用することができない。**
nilを代入すると、コンパイルエラーが発生してしまいます。

Optional Typeは、nil(空の値)を使用することができる型のひとつです。

```swift:Demo-4.swift

// Optional Typeの宣言1
// 宣言のみの場合、初期値はnil
var str1: Optional<String>
print(str1) // nil

// Optional Typeの宣言2 (上と同じこと)
// 宣言のみの場合、初期値はnil
var str2: String?
print(str2) // nil


var str3: String? = "foo"
// nilの代入も可能
str3 = nil
print(str3) // nil
```

**String?は「Optional Type」で、「String」とは型が異なるため**
**Stringのメソッドは使用することができない。**

イメージとしては、以下のStringの配列(Array型)が、Stringのメソッドを呼び出せていないのと同じです。
<img width="517" alt="2017-04-10 2.52.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/103695/66be96a1-513c-286b-2582-686b3bdb734e.png">

String?をStringとして使用するために**unwrap(アンラップ)**をする必要があります。

unwrap: **Optional\<T>からT型の変数を取り出すこと。**
(Tは、StringやIntのような型を示します。)

## unwrap1. Forced Unwrapping 

nilかどうかに関わらず強制的にアンラップする。**nilだった場合は、クラッシュしてしまう。**
`fatal error: unexpectedly found nil while unwrapping an Optional value`

```swift:Demo-5.swift
var text: String?

text = "foobar"
// !を付けて、強制アンラップして、Stringとして使用
let newText1 = "[new]" + text!
print(newText1) // [new]foobar
        
text = nil
// !を付けて、強制アンラップして、Stringとして使用
let newText2 = "[new]" + text!
print(newText2) // クラッシュ
```

クラッシュはまずいので、**基本的に使わない方が良いと思います。**

## unwrap2. Nil Coalescing Operator
もし、nilだったらデフォルト値を入れる。
`??`という演算子を使用する。

```swift:Demo-6.swift
/// nameプロパティだけを持つ単純なクラス
final class Man {
    // Optional Type
    static var name: String?
}

final class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 定義するnameは、String型
        // Man.nameがnilだった場合は、"unknown"が入る
        let name = Man.name ?? "unknown"
        print(name)
    }
}
```

## unwrap3. Optional Binding
もし、nilではなかったら、処理をする。
nil判定と、定数化を一緒にしてくれるイメージです。

```swift:Demo-7.swift
var array: [String] = ["a", "b", "c", "d", "e"]

// array.firstがnilでなければ、firstElementを定義してifブロック内の処理を実行
if let firstElement = array.first {
    // firstElementは、このifブロック内でのみ有効
    print("firstElement is \"\(firstElement)\"")
}

print("count: \(array.count)")
```

## unwrap4. Optional Chaining
もし、nilではなかったら、そのプロパティやメソッドにアクセスする。
**Optional Chainingの呼び出し結果はOptional Typeになる。**
そのため、上記のNil Coalescing OperatorやOptional Bindingを併せて使用します。


```swift:Demo-8.swift
var count: Int? = 0

// textがnilの場合はnilが返却される
// textがnilでない場合は文字数が返却される(Optional Type)
count = textField.text?.characters.count
```

```swift:Demo-9.swift
// Nil Coalescing Operatorを使用する場合
let count = textField.text?.characters.count ?? 0
print(count)
```

```swift:Demo-10.swift
// Optional Bindingを使用する場合
if let count = textField.text?.characters.count {
    print(count)
}
```

## unwrap5. Guard Statement
もし、nilだったらその場で処理を終了する。(早期リターンする)

```swift:Demo-11.swift
func outputWomanName(woman: Woman?) -> Bool {
        
    // womanがnilの場合は早期リターンする
    guard let woman = woman else {
        return false
    }

    // womanがnilでない場合はunwrapしたwomanを使用できる
    print("name: \(woman.name)")
    return true
}
```
## Implicitly Unwrapped Optional
Optional Typeの操作ではなく、**型**のひとつとしてImplicitly Unwrapped Optionalがあります。

暗黙的にForced Unwrappingが行われる。
Forced Unwrappingと同様に**nilだった場合は、クラッシュしてしまう。**
`fatal error: unexpectedly found nil while unwrapping an Optional value`

```swift:Demo-12.swift
var str: String! = "foo"
print(str)
        
str = nil
print(str) // クラッシュ
```

クラッシュはまずいので、Forced Unwrappingと同様にこちらも**基本的に使わない方が良いと思います。**

# さいごに
今回は、
・変数と定数
・型推論
・Optional Type (オプショナル型)
について纏めました。
どんどん追加・更新していきたいです。