Swift基礎構文


ざっと書きました。すごく見ずらいです

***

行末尾に;は必要ない（あってもいいが基本はつけない）

##・変数定数
変数：　var
定数：　let


##・基本は型推論だがこちらから指定もできる
例）

```swift
var a: String = "hello"
```

##・文字列の中で「＼」を使うと変数や式などを混ぜることができる
例）

```swift
var name = "Taro"
print ("hello \(name)")
```



##・nilの扱い方
Swiftでの「nil」は「何もない状態」のこと
nilになりえるデータ型となりえないデータ型がある
例えばStringやIntはnilになりえない（代入するとエラーになる）
もし代入される恐れがある場合は「Optional型」を指定してあげる必要がある
例）

```swift

var a: Optional<String> = nil
```

↓簡略

```swift

var a: String? = nil
```

Optional型を使うときはその値がnilかどうかチェックする必要がある
例）

```swift

if s != nil {
    print (s!)
}
```

この処理を「unwrap」という
ただこの書き方よりもOptional Bindingという書き方がよくつかわれるらしい
例)

```swift

if let value = s {
    print (value )
}
```

これはsをunwrapしてvalueに代入しているらしい
またもう一つよくあるかきかたで

```swift

print (s ?? "this is nil")
```
というのがあるらしい
これはもしsがnilじゃなければ左辺を出力してnilであれば右辺を出力するという処理になる


##・配列
要素配列状に記録する
例）

```swift

var users = ["Tanaka", "Ueda", "Sato", "Inoue"]
```
これも型をこちらで指定できる。

空の配列の作り方

```swift

var names = [String]()
```

値の取り出し方

```swift

print (users[0]) //Tanaka
```

for文ですべての配列の値を取り出すこともできる
例）

```swift

for user in users {
    print (user)
}
```


##・タプル
タプルとは、簡単に言うと違う型の値をひとまとめにすることができる（？）
例)

```swift

var velue = ("apple", 120)
```
valueにString型とInt型の二つを代入している

```swift

print (value.0) //apple
print (value.1) //120
```
タプルの要素を変数や定数に代入して取り出す方法もよく使われているらしい
例)

```swift

let (product, amount) = value
print (product) //apple
print (amount) //120
```
このとき片方を使わないという場合にはそのようにする書き方がある
例）

```swift

let (product, _) value
```
この「_」はよく使われるらしい

また初期化するときにあらかじめ名前を付けることもできる
例）

```swift

var value = (product: "apple", amount: 120)
```
タプルはよく使われるらしいので意識して覚える


##・集合
Set型
書き方

```swift

var numbers: Set = [5, 8, 9]
```
空の場合

```swift

var numbers: Set<Int>()
```
値があるかの確認「contains」
例）

```swift

print (numbers.contains[5]) //true
```
値の追加と削除「insert」「remove」

```swift

numbers.insert(10)
numbers.remove(5)
````
和集合、積集合、差集合

```swift

var a: Set = [5, 8, 9, 10]
var b: Set = [5, 7, 8, 10, 11]

和
print(a.union(b)) // 5, 7, 8, 9, 10, 11

積
print(a.intersection(b)) // 5, 8, 10

差
print(a.subtracting(b)) // 7, 9, 11
```

##・辞書型
Dictionary型

```swift

var scores: Dictionary<String, Int> = [
          "Tanaka": 40,
          "Ueda": 34,
          "Sato": 70,
]

```
短い書き方だと、

```swift

var scores = [
          "Tanaka": 40,
          "Ueda": 34,
          "Sato": 70,
]
```
値の変更や取り出し

```swift

scores["Tanaka"] = 50
print (scores["Tanaka"])
```
こうするとkey”Tanaka”の値を５０をに入れ替えたので50が表示されるはずですが、これだけでは不完全
なぜかというとDictionaryでkeyを指定すると値が入っていない場合（nilの可能性）があるのでOptional型で帰ってきてしまう
先の書き方だと

```swift

print(scores["Tanaka"]) // Optional(50)
```

となってしまう
これを防ぐために、nilの場合どうするかを明示的に書いてあげる必要がある
先の「nilの扱い方」にのっとって

```swift

print(scores["Tanaka"] ?? 0) // 50
```
配列と同じようにforで値を取り出せる
例）

```swift

for (key, value) in scores {
          print("\(key): \(value)")
}
```
keyの取り出しには「.keys」を使う


```swift

var a = [
    "apple": 100,
    "banana": 200,
]
print(Array(a.keys)) // ["apple", "banana"]
```
空のDictionary

```swift

var a = [String, Int]()
```



##・関数
その宣言を呼び出したときに定義した処理をする
宣言の仕方

```swift

func 関数名(){処理}
```
「func」は関数の宣言
「say()」はその関数の名前。名前の後ろに()をつけてあげる必要がある

呼び出しはその関数の名前を書いてあげればいい
例）

```swift

func sayHi(){
    print ("hi")
}
sayHi() // hi
```
その関数を呼び出したときに値を返してもらうこともできる（戻り値）
例）

```swift

func sayHi() -> String {
    return "hi"
}
print (sayHi) // hi
```
「-> String」で戻す値の型を宣言している。これをしないとエラーになってしまう。


・引数
先の「戻り値」は関数を呼び出すとその呼び出し関数から値を戻してくれるものだったんですが
この「引数」はその逆（？）
呼び出した関数に値を渡すことができる
（）の中に書いてあげます
例）

```swift

func sayHi(name: String){
    print("hi \(name)")
}
sayHi(name: "tom") // hi tom
```

これは

```swift

func sayHi(変数名: 型){}
```
となっています
呼び出し元では

```swift

sayHi(変数名: 渡したい値)
```
となっています
渡すことができればその変数を関数の中で使うことができるので

```swift

print("hi \(name)") // hi tom
```
となっています

また実行するときの変数と呼び出すときの変数を別々のものにすることもできる
たとえばsayHi(name: "tom")だけではトムがあいさつしているのかトムに挨拶しているのかがあいまいなのでここの変数を変えてみましょう

```swift

func sayHi(from name: String){
    print("hi \(name)")
}

sayHi(from: "tom") // hi tom

```
関数sayHiの（）の中が
from name
となっていますが、これは関数の変数nameにfromというラベルを付けてあげています

また呼び出し元に変数をつけたくないとき、

```swift

func sayHi(_ name: String){
    print("hi \(name)")
}

sayHi("tom") // hi tom
```
「_」こちらを使うことで実現できます。


##・inout
さきの引数で値を渡すことができることを書いたんですが、実は渡した際に値を受け取る名前は変数ではなく定数になっています

```swift

func sayHi(name（←定数）: String){}
```
そのため以下のような処理をするとエラーが起きてしまします

```swift

func num(x: Int) {
    x +=5
    print (x)
}
```
ただやはり受け取った値を変更したいときもありますのでそのときは「inout」というキーワードをつけてあげます

```swift

func num(x: inout Int) {
    x +=5
    print (x)
}
```

ただこのinoutを使うにあたって注意点がある

```swift

func num(x: inout Int) {
    x +=5
    print (x)
}

var i = 10

num(x: &i)

```
このようにしてあげる必要がある

このときnum()でxに5を足しているんですが、書き変わった結果をiにも反映しているので

```swift

print (i) // 15
```
このような結果になる


##・クラスの作成

class クラス名 {}
クラスの中に存在する変数や定数を「propaty」という
例）

```swift

class User {
        let name: String // propaty
        var score: Int
}
```

propatyに値を持たせるには「init()」を使用する

```swift

class User {
        let name: String
        var score: Int
        
        init(){
                self.name = "Ueda"
                self.socore = 50
        }
}
```
ここでの「self」は「Userクラスの」という意味になる

##・インスタンスの作成
作ったクラスを使用できるようにする

```swift

let user = User()

print(user.name) // Ueda
print(user.score) // 50
```

##・イニシャライザ
先ほどのイニシャライザ[init()]に値を渡すこともできる
インスタンスを作成するときに値を渡してそれをイニシャライザで受け取る
例）

```swift

class User {
        let name: String
        var score: Int
        
        init(name: String, score: Int){
                self.name = name
                self.score = score
        }
}

let user = User(name: "Tanaka",score: 80)

print(user.name) // Tanaka
print(user.score) // 80
```
この時に宣言する変数名などは先の引数などと同様にラベルを付けて変数名を変えたり、「_」を使用することができる

またイニシャライザは複数用意することができる
例)

```swift

class User {
        let name: String
        var score: Int
        
        init(name: String, score: Int){
                self.name = name
                self.score = score
        }
        
        init(name: String){
                self.name = name
                self.score = 0
        }

        init(){
                self.name = "noneName"
                self.score = 0
        }
}

let user = User(name: "Tanaka",score: 80)
let user2 = User(name: "Tanaka")
let user3 = User()

print(user.name) // Tanaka
print(user.score) // 

print(user2.name) // Tanaka
print(user2.score) // 0

print(user3.name) // noneName
print(user3.score) // 0
```
これは結果を見てわかる通り、インスタンス化する際の引数の違いで呼ばれるイニシャライザもかわってくる


##・計算プロパティ
プロパティは動的に計算させることができる

```swift

class User {
        var score: Int
        var level : Int {
                get {
                        return Int(self.score / 10)
                }
                set {
                        self.score = newValue * 10
                }
        }
        init() {
                self.score = 40
        {
}
```
計算しているプロパティは

```swift

var level : Int {
                get {
                        return Int(self.score / 10)
                }
                set {
                        self.score = newValue * 10
                }
        }
```
この部分になる

これはなにをしているかというと「get」でlevelの値を取得してまた「set」でscoreに値を入れている

なのでこの場合
「level」の値は「score」の10分の1になり「score」は「level」の10倍になる
となる

```swift

class User {
        var score: Int
        var level : Int {
                get {
                        return Int(self.score / 10)
                }
                set {
                        self.score = newValue * 10
                }
        }
        init() {
                self.score = 50
        {
}

let user = User()

print (user.score) // 50
print (user.level) // 5

user.score += 10
print (user.score) // 60
print (user.level) // 6

user.score -= 3
print (user.score) // 30
print (user.level) // 3
```
またsetをしないgetだけの書き方もありその場合は

```swift

var level: Int {
        return Int(self.score / 10)
}
```
このようになる


##・プロパティの値の監視
プロパティに変更があったとき動的に処理を行うこともできる
例えばscoreの監視をする際にはこういった書き方をする    

```swift

var score: Int {
    willSet {
    }
    didSet {
    }
}
```  

willSetについては値の変更がされる前に行われる処理、didSetが書き換わったあとに変更される処理となる
willSetの処理の中で「newValue」というキーワードを使うと変更後の値が取得できる
逆にdidSetの処理の中で「oldValue」というキーワードを使うと変更される前の値を取得することができる
例）

```swift

class User {
    var score: Int {
        willSet {
            print ("\(score) -> \(newValue)")
        }
        didSet {
            var i = 0
            i = score - oldValue
            if i > 0 {
                print ("Changed: +\(i)")
            } else {
                print ("Changed: \(i)")
            }
        }
    }
        
    init() {
        self.score = 50
    }
}

let user = User()

user.score = 40
user.score = 60

// 結果
// 50 -> 40
// Changed: -10
// 40 -> 60
// Changed: +20
```
またこのwillSetとdidSetに関しては初期化するときには実行されない


##・メソッド
簡単に言うとクラスに紐づけられた関数
用語としてメソッドと関数がごっちゃになるので覚えておくようにしたい
使用方法としてはインスタンス化した変数を呼び出す方法と同じで関数名を打ち込んであげればいい
例）

```swift

class User {
    var score: Int  
    
    init() {
        self.score = 50
    }
    
    func addScore(){
        self.score += 10
        print (self.score)
    }
}

let user = User()

user.addScore() // 60
```
もちろんこちらにも戻り値や引数も使える


##・クラスの継承
ほかの言語と同様継承ももちろんできる
例えばさきのUserクラスを継承してPersonクラスを作ってみる

```swift

class User {
    var score: Int  
    
    init() {
        self.score = 50
    }
    
    func addScore(){
        self.score += 10
        print (self.score)
    }
}

class Person: User {
    
}
```
このPersonクラスはUserクラスを継承しているのでその中身のプロパティやメソッドなども扱うことができる
例）

```swift

class User {
    var score: Int  
    
    init() {
        self.score = 50
    }
    
    func addScore(){
        self.score += 10
        print (self.score)
    }
}

class Person: User {
    
}

let person = Person()

person.score = 90
person.addScore() // 100
```
継承元のクラスのことを親クラス（スーパークラス）、そのクラスをもとに作ったクラスを子クラス（サブクラス）という


##・オーバーライド
継承もとのメソッドを使えることはもちろんだが、そのメソッドサブクラスで再定義することができる
これをオーバーライドという
オーバーライドするときは明示的に宣言する必要があり、そのメソッドの頭に「override」として挙げる必要がある
例）

```swift

class User {
    var score: Int  
    
    init() {
        self.score = 50
    }
    
    func addScore(){
        self.score += 10
        print (self.score)
    }
}

class Person: User {
    override func addScore(){
        self.score += 40
        print (self.score)
    }
}

let person = Person()

person.score = 90
person.addScore() // 130
```
また継承元のクラスで、そのメソッドをオーバーライドされたくないとき、
そのときは継承元のクラスでそのメソッドに「final」をつけてあげるといい

```swift

class User {
    var score: Int  
    
    init() {
        self.score = 50
    }
    
    final func addScore(){
        self.score += 10
        print (self.score)
    }
}

class Person: User {
    override func addScore(){
        self.score += 40
        print (self.score)
    }
}

let person = Person()

person.score = 90
person.addScore() // エラー

```
##・staticな要素
クラスのメソッドやプロパティにstaticをつけることでインスタンス化しなくても直接クラスから呼び出せるようにすることができる

```swift

class User {
    var score: Int
    static var count = 0
    
    init() {
        self.score = 50
        User.count += 1
    }
    
    static func getInfo() {
        print (User.count)
    }

}

User.getInfo() // 0
let user = User()
User.getInfo() // 1
```
この処理の流れを説明すると
まず以前のクラスたちの違いとしてstaticな変数「count」とstaticなメソッド「getInfo()」がある
まずクラスの下で最初にクラスから直接getInfo()を呼び出している（User.getInfo()）
何も処理はしていないので当然帰ってくる値は初期化したままの０
次にUserクラスをインスタンス化している
インスタンス化するときに必ずイニシャライザが呼ばれるが処理を見るとそのイニシャライザでUserのcount に1足している
そのためその下で再度getInfo()を呼び出すと１として値が返される
もちろんこのcountもstaticな要素なのでインスタンス化せずに直接操作することができる
逆にインスタンス化して
user.count = 100
などするとエラーになる 

例）

```swift

class User {
    var score: Int
    static var count = 0
    
    init() {
        self.score = 50
        User.count += 1
    }
    
    static func getInfo() {
        print (User.count)
    }

}


User.count = 100
User.getInfo() // 100
```
だが

```swift

class User {
    var score: Int
    static var count = 0
    
    init() {
        self.score = 50
        User.count += 1
    }
    
    static func getInfo() {
        print (User.count)
    }

}


User.count = 100
User.getInfo() // 100

let user = User()
user.coutn = 100 // エラー
User.getInfo()
```
エラーになってしまう


##・型キャスト
あるクラスをほかのクラスに変換すること
書き方

```swift

class User {
    let name: String
    init(_ name: String){
        self.name = name
    }
}

class AnotherUser: User {
    
}

let user = User("sato") //型　-> User
let another = AnotherUser("fujisaki") // 型 -> AnotherUser

let users = [user, another]
```
2つのインスタンス、userとanotherを配列にしてまとめています。
ここでswiftが自動でanother型「AnotherUser」はuserの型「User」を継承していると判断しているためまとめることができる。継承などを行っていない全く違う型同士だとエラーが発生してしまう
例）エラー

```swift

class User {
    let name: String
    init(_ name: String){
        self.name = name
    }
}

class AnotherUser: User {
    
}

class Person {
    let name: String
    init(_ name: String){
        self.name = name
    }
}

let person = Person("takeshi")
let user = User("sato")
let another = AnotherUser("fujisaki")

let users = [user, another, person] // エラ-
```
これはOK

```swift

class User {
    let name: String
    init(_ name: String){
        self.name = name
    }
}

class AnotherUser: User {
}

class Person: User {
}

let person = Person("takeshi")
let user = User("sato")
let another = AnotherUser("fujisaki")

let users = [user, another, person] //　OK!!
```
ただ実際の処理ではクラスごとに分けたいので別途指示してあげる必要がある

まず配列になっているのでfor文でループ処理をする
そのときにAnotherUserの場合にnameを表示させる
「as」というキーワードを使ってuserがAnotherUserか判断する

```swift

class User {
    let name: String
    init(_ name: String){
        self.name = name
    }
}

class AnotherUser: User {
    
}

let user = User("sato")
let another = AnotherUser("fujisaki")

let users = [user, another]

for user in users {
    if let u = user as? AnotherUser {
        print (u.name)
    }
}
```

##・プロトコル
クラスに対して、指定したプロパティやメソッドの実装を強制する
例）

```swift

protocol Shutter {
    var count: Int { get set }
    var flash: Bool { get set }
    func flashChange()
    func push()
}


class Camera: Shutter {
    let name: String
    var count: Int
    var flash: Bool
    
    init(){
        self.name = "Camera"
        self.count = 0
        self.flash = true
    }
    
    func flashChange() {
        self.flash = !flash
    }
    
    func push() {
        self.count += 1
        print ("シャッターが押されました")
        if flash == true {
            print ("フラッシュ：ON")
        } else {
            print ("フラッシュ：OFF")
        }
        print ("シャッター回数は \(count) 回目です")
    }
    
    func test(){
        print("test")
    }
}

let camera = Camera()

camera.flashChange()
camera.push()
```
作成するときには「protocol」で宣言してあげる
protocol内では実装することを指定してあげるだけなので初期化などはしなくてもいい
そのプロコトルをクラスに紐づけるためにクラス名の横にプロコトル名を宣言する

```swift

class Camera: Shutter

```
##・エクステンション

型の拡張

例えばSwiftで文字列の文字数をカウントするには

```swift

var str = "abcdefghi"
print(str.characters.count)
```
として挙げる必要がある
これを

```swift

print(str.lengh)
```
これだけでカウントするようにString型を拡張してみる

```swift

extension String {
    var length: Int {
        return self.characters.count
    }
}

var str = "abcdefghi"

print(str.characters.count) // 9
print(str.length) // 9
```

##・値型と参照型
Swiftには主に2つのデータ型がある
IntやDouble、配列などの型は値型
逆にClassだけは参照型になる

違いとしては
引数や変数として渡されるときの挙動が変わってくる
例えば

```swift

var a = 20
var b = a
a = 30
print (a) //30
print (b) // 20
```
これはまずaに20を代入してそのaをbに代入している
そのあとにaに30を代入しているがbにはaの元の値（20）が代入されているだけなので表示をさせるとaが３０、bが２０となる
ここまでは特に問題はないのだが参照型になるとこの変わってくる

```swift

class User {
    var name:String
    init(name: String){
        self.name = name
    }
}

var user = User("ueda")
user.name = "tanaka"
```
ここまでは普通だが、インスタンス化したuserを別の変数に代入する

```swift

ver copy = user
```
このときどのような処理になっているかというと、
この「copy」はuserが格納されている場所となる
なので例えば

```swift

print (user.name) // tanaka
```
となるが

```swift

print (copy.name) // tanaka
```
同じくこちらもこうなる
こうしてもあくまでcopyはuserの格納されている場所をしめすので結果的にはuser.nameを示すことになる

```swift

class User {
    var name:String
    init(name: String){
        self.name = name
    }
}

var user = User("ueda")
ver copy = user

user.name = "tanaka"

print (user.name) // tanaka
print (copy.name) // tanaka
```

##・構造体
struct型
このstruct型は基本的にはclassと同じような使い方をする
例）

```swift

struct User {
    var name: String
    init(_ name: String){
        self.name = name
    }
}

var user = User("ueda")
```
ただクラスと違うところがあり、まず一番の違いは
classは参照型だがstructは値型になる
なので先ほどのインスタンス化したクラスを別の変数に代入するとそのデータの場所が変数に格納されるというものでしたが、このstructの場合は値が格納されることになる
例）

```swift

struct User {
    var name: String
    init(_ name: String){
        self.name = name
    }
}

var user = User("tanaka")
var copy = user //userの値
user.name = "ueda"

print (user.name) // ueda
print (copy.name) // tanaka

```
またそのままではメソッドからプロパティを変更することができない
例えば

```swift

struct User {
    var name: String
    init(_ name: String){
        self.name = name
    }
    
    func changeName() {
        self.name = "sato"
    }
}
```

こうするとエラーが出てしまう
これを防ぐためにプロパティを変更するときは明示的に「mutating」というキーワードをつける必要がある

```swift

struct User {
    var name: String
    init(_ name: String){
        self.name = name
    }
    
    mutating func changeName() {
        self.name = "sato"
    }
}
```
そしてclassと違う点としてもう一つ、こちらは継承をすることができない
extensionやprotocolは使うことできるので拡張するばあいはこちらで行う。


##・列挙型
enum
値をまとめて型にしたもの

```swift

enum 型名 {
    case データ1
    case データ2
    case データ3
    case データ4
}
```
まとめた値についての処理をしたい場合、その値を取り出して処理を行っていく
例）

```swift

enum Ver {
    case iPhone6
    case iPhone7
    case iPhone8
    case iPhone9
    case iPhoneX
}

var ver: Ver
ver = Ver.iPhone6

switch (ver) {
    case .iPhone6:
    print ("This iPhone is \(ver)")
    case .iPhone7:
    print ("This iPhone is \(ver)")
    case .iPhone8:
    print ("This iPhone is \(ver)")
    case .iPhone9:
    print ("This iPhone is \(ver)")
    case .iPhoneX:
    print ("This iPhone is \(ver)")
}
```
この時、データをすべてcase文に書いていない、またはdefaul処理を行っていない場合エラーになる

また列挙型のデータに対して文字列は数字の値を割り当てることができる
割り当てる型を宣言してあげてそれぞれのデータに代入していく

```swift

enum Ver :String{
    case iPhone6 = "ios6"
    case iPhone7 = "ios7"
    case iPhone8 = "ios8"
    case iPhone9 = "ios9"
    case iPhoneX = "ios10"
}
```
この割り当てた値に対しては「rawValue」を使い取り出すことができる

```swift

enum Ver :String{
    case iPhone6 = "ios6"
    case iPhone7 = "ios7"
    case iPhone8 = "ios8"
    case iPhone9 = "ios9"
    case iPhoneX = "ios10"
}

print(Ver.iPhone6.rawValue) // ios6
```


##・ジェネリクス
メソッドなどの作成のさい、使いまわしができるように型を汎用的にさせることができる
例えば何か表示させるメソッドを作りたいと思ったとき

```swift
func show(_ x: String){
    print (x)
}

show("hello")
```
このような処理になる

ただこの処理を例えばInt型を表示させたい。Double型を表示させたいとなった場合、それぞれの処理を書かなければいけなくなりコードが肥大化してしまう。それを解決するためにこのメソッドの型を汎用化させる

メソッド名の後ろに「\<T>」を記入してあげて引数の型も「T」にしてあげる
ちなみにこの「T」とくに指定はないようだが、Typeの「T」がよく用いられるそう。


```swift
func show<T>(_ x: T){
    print (x)
}
```
これで型が汎用化されたので引数に文字列、数字と入れても処理をしてくれる

```swift

func show<T>(_ x: T){
    print (x)
}

show("hello") // hello
show(555) // 555
```


##・サブスクリプト
インスタンスに対して、配列などのようにインデックスをつけられるようにする

```swift

class User{
}

let user = User()
user[0]
```
サブスクリプトを使うためにはクラス側でそのインデックスに対する配列と処理を記入する
クラスで作成する配列についてはとくに通常通りだが、処理に関しては「subscript」と宣言する

```swift

class User {
    var users = ["ueda", "tanaka", "sato"]
    subscript(index:Int) -> String {
        get {
            return users[index]
        }
        set {
            users.insert(newValue, at:index)
        }
    }
}

let user = User()

print (user[0]) // ueda
user[0] = "kikuchi"
print (user[0]) // kikuchi
```
subscriptの引数indexにはsubscriptで呼ばれる型、今回は整数だったのでInt、引数には文字列を返すので
->Strng
としてあげた
処理のなかの「get」と「set」に関しては計算プロパティとほとんど同じ
値を取得する処理をgetに、設定する処理をsetにする
値を取得するだけならばsetの処理は書かなくてもいい


##・guard
異常処理をわかりやすくする

適当に異常処理が発生する処理を書いてみる

```swift
func show(_ item: String?) {
    if let value = item {
        print (item)
    } else {
        print ("There is not item")
    }
}

show(nil) // There is not item
```

これで異常理が発生した際にThis can't runの文字列が表示されるようになった。
ただこれだとコードが肥大化したときにわかりづらくなる
###「early return」と「early exit」をつかう
これは異常な処理などが発生した場合、すぐに処理を抜けるというような書き方をする

```swift

func show(_ item: String?) {
    if item == nil {
        print ("There is not item")
        return
    } else {
        print (item!)
    }
}

show(nil) // There is not item
show("apple") // apple
```
最初にitemがnilかどうか判断してあとからunwrapして表示させるという処理になっている
ただこれではまだ可読性は高いとは言えない

そこで「guard」を使用する

```swift

func show(_ item: String?) {
    guard let s = item else {
        print ("There is not item")
        return
    }
    print (s)
}

show(nil) // There is not item
show("hi")
```
もしitemがnilでなければsに代入、そうでなければelseの処理をするという具合になる
ちなみにguardを使用するとunwrapしても変数をそのまま使用することができるので後の「print (s)」に「!」を使用していない

##・Optional Chaining