Swiftの基本（version 5.9.2）

# 基本

| 項目 | 説明 |
| --- | --- |
| 整数 | Int |
| 浮動小数点数 | Double<br>Float |
| 真偽値 | Bool |
| テキストデータ | String |
| コレクション | 配列<br>セット<br>辞書 |
| タプル | 値のグループ化を作成し、渡すことが可能<br>使用することで、単一の複合値として関数から複数の値を返すことが可能 |
| オプショナル | 値の不在を扱う<br>どちらかの内容を表現<br>　・値があり、それはxに等しい<br>　・値が全くない |

| 項目 | 説明 |
| --- | --- |
| 変数 | 識別名によって値を格納し、参照するために使用 |
| 定数 | 値を変更することができない
変更する必要のない値を扱うときに、コードをより安全で明確な意図にするために使用 |
- Swiftは型安全言語
    - コードが扱うことができる値の型を明確にすることを助ける言語
    - 型安全性
        - 開発プロセスのできるだけ早い段階でエラーを発見し、修正するのに役立つ
        - 例
            - コードの一部がStringを必要とする場合に、間違ってIntを渡すことを防ぐ
            - オプショナルでないStringを必要とするコードに、誤ってオプショナルなStringを渡すことを防ぐ

# 定数と変数

- 定数と変数
    - 名前と特定の型の値を関連付けます
    - 定数の値は一度設定すると変更できません
    - 変数の値は将来別の値を設定することが可能

## 定数と変数の宣言

- 定数と変数は、使用する前に宣言する必要がある
    - 定数は let キーワード
    - 変数は var キーワード

```swift
let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0
```

- コードに格納された値が変化しない場合は常に let キーワードで定数として宣言
- 変数を使用するのは、変化する値を格納する場合だけ
- 定数や変数を宣言
    - 宣言の一部として値を与えることが可能
    - プログラムの後半で初期値を代入することも可能

```swift
var environment = "development"
let maximumNumberOfLoginAttempts: Int

if environment == "development" {
    maximumNumberOfLoginAttempts = 100
} else {
    maximumNumberOfLoginAttempts = 10
}
```

複数の定数や複数の変数をカンマ区切りで1行に宣言可能

```swift
var x = 0.0, y = 0.0, z = 0.0
```

## 型注釈

定数や変数を宣言するときに型アノテーションを記述

- 定数や変数が格納できる値の種類を明確化
- 記述方法
    - 定数または定数名の後にコロン
    - その後にスペース
    - その後に使用する型名を記述

```swift
var welcomeMessage: String
```

同じ型の複数の関連変数をカンマで区切って1行に定義し、最後の変数名の後に1つの型注釈を付けることも可能

```swift
var red, green, blue: Double
```

### **注記**

型注釈を書く必要があることはあまりない

- 定数や変数が定義された時点で初期値を提供する場合、型推論が実行されるため
- 初期値がない場合に使用
    - 初期値がないと型推論できないため

## 定数と変数の命名

定数名と変数名に設定できない内容

- 空白文字
- 数学記号
- 矢印
- 私用Unicodeスカラー値（private-use Unicode scalar values）
- 線描画文字
- 枠描画文字
- 数字で始める
    - 始め以外に含めることは可能

定数や変数を一度宣言するとできないこと

- 同じ名前で再び宣言
- 別の型の値を格納するように変更すること
- 定数と変数を切り替える

既存の変数の値を、互換性のある別の型の値に変更は可能

```swift
var friendlyWelcome = "Hello!"
friendlyWelcome = "Bonjour!"
```

変数とは異なり、定数の値は設定後に変更することはできない

## 定数と変数の表示

定数や変数の現在値を表示

- print(_:separator:terminator:)関数を使用

```swift
print(friendlyWelcome)
```

print(*:separator:terminator:) 関数*

- *1つ以上の値を適切な出力にプリントするグローバル関数*
- separator と terminator パラメータにはデフォルト値がある
    - デフォルト
        - 改行を追加することによって、出力する行を終了

文字列補完

- 名前を括弧で囲み、開始括弧の前にバックスラッシュでエスケープ

```swift
print("The current value of friendlyWelcome is \(friendlyWelcome)")
```

# コメント

```swift
// 1行コメント

/*
	複数行コメント
*/

/*
	複数行コメント
	/*
		入れ子も可能
	*/
*/
```

# セミコロン

セミコロンは基本的に記述する必要はない

- 1行に複数の別々のステートメントを書きたい場合に必要

```swift
let cat = "🐱"; print(cat)
```

# 整数

整数は小数部を持たない整数

- 符号あり
    - 正
    - ゼロ
    - 負
- 符号なし
    - 正
    - ゼロ

提供する整数

- 符号付き整数
    - 8, 16, 32, 64 ビット形式
- 符号なし整数

Cに似た命名規則

- 8ビットの符号なし整数はUInt8型
- 32ビットの符号付き整数がInt32型

## 整数の境界

各整数型の最小値と最大値には、min プロパティと max プロパティでアクセス

```swift
let minValue = UInt8.min
// 0
let maxValue = UInt8.max
// 255
```

## Int型

基本的にコードで使用する整数の特定のサイズを選択する必要はない。
Swiftが現在のプラットフォームのネイティブワードサイズと同じサイズを持つ、整数がIntを提供するため

- 32ビットプラットフォームでは、IntはInt32と同じサイズ
- 64 ビットプラットフォームでは、Int は Int64 と同じサイズ

**特定のサイズの整数を扱う必要がない限りは、コードないの整数値には常にIntを使用**

- コードの一貫性
- 相互運用性

## UInt型

UIntは、プラットフォームのネイティブ・ワード・サイズと同じサイズの符号なし整数型が特に必要な場合にのみ使用。
そうでない場合は、**格納される値が非負であることが分かっている場合でも、Intの使用を推奨**

- 相互運用性
- 整数型推論

# 浮動小数点数

浮動小数点数とは、小数要素を持つ数値のこと

- 3.14159
- 0.1
- -273.15

浮動小数点型は整数型よりもはるかに広い範囲の値を表現可能なため、
Intに格納できるより

- はるかに大きい
- 小さい

数値を格納可能

Swiftは 2 つの符号付き浮動小数点数型を提供

- Doubleは64ビット浮動小数点数
- Floatは32ビット浮動小数点数

## 注記

精度

- Doubleは少なくとも小数点以下15桁
- Floatは小数点以下6桁

適切な浮動小数点型は、コードで扱う必要のある値の性質と範囲によって決定するが、
**どちらも適切な状況ではDobuleを推奨**

# 型安全性と型推論

型安全な言語は、コードが扱うことができる値の型を明確にすることを推奨

- コードがStringを必要とする場合、間違ってIntを渡すことはできない

Swiftは型安全言語

- コードをコンパイルするときに型チェック
- 不一致の型はエラー
- 開発プロセスのできるだけ早い段階でエラーを発見、修正が可能

型推論

- コンパイラがコードをコンパイルするときに提供された値を調べる
- 自動的に特定の式の型を推測
- 初期値を持つ定数や変数を宣言するときに特に役立つ

```swift
// Intであることを推論
let meaningOfLife = 42

// Doubleであることを推論
// 浮動小数点数の型を推測するとき、常に（Float ではなく）Double を選択
let pi = 3.14159

// 式で整数と浮動小数点リテラルを組み合わせた場合、Double の型をコンテキストから推論
// リテラル値3は、それ自体では明示的な型を持たないため、
// 加算の一部として浮動小数点リテラルが存在することから、適切な出力型Doubleを推論
let value = 3 + 0.14159
```

# 数値リテラル

```swift
// 下記はすべて17
let decimalInteger = 17
// 10進数
let binaryInteger = 0b10001
// 2進数
let octalInteger = 0o21
// 8進数
let hexadecimalInteger = 0x11
// 16進数
```

浮動小数点リテラル

- 10進数（接頭辞なし）または16進数（接頭辞0x付き）
- 小数点の両辺には必ず数値（または16進数）を指定
- 16進数浮動小数点は指数を持たなければならず、大文字または小文字のpで示される

指数がxの10進数の場合、基数は10ˣ乗

- 1.25e2は1.25×10² → 125.0
- 1.25e-2は1.25×10-² → 0.0125

指数がxの16進数の場合、基数は2ˣ乗

- 0xFp2は15 x 2² → 60.0
- 0xFp-2は15×2-² → 3.75

```swift
// 下記はすべて12.1875
let decimalDouble = 12.1875
let exponentDouble = 1.21875e1
let hexadecimalDouble = 0xC.3p0
```

数値リテラルには、読みやすくするための特別な書式を含めることが可能

- 整数も浮動小数点も可能
- 読みやすくするためにゼロを追加したりアンダースコアを入れたりできる
- どちらの書式設定も、リテラルの基本的な値には影響しない

```swift
let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1
```

# 数値型の変換

**コード内のすべての汎用整数定数や変数には、たとえそれが非負であることがわかっていても Int 型を使用**

日常的な場面でデフォルトの整数型を使用することは、整数定数や変数がコード内ですぐに相互運用でき、整数リテラル値の推論型と一致することを意味

他の整数型は、手元のタスクに特別に必要な場合にのみ使用

- 外部ソースから明示的にサイズを指定されたデータ
- パフォーマンス
- メモリ使用量
- その他の必要な最適化

このような状況で明示的にサイズ指定された型を使用する意図

- 偶発的な値のオーバーフローを検出しやすくなる
- 使用されるデータの性質が暗黙のうちに文書化

## 整数変換

各数値型は異なる範囲の値を格納することが可能

- 数値型変換はケースバイケースで選択する必要がある
- 隠れた変換エラーを防ぎ、コード内で型変換の意図を明示するのに役立つ

ある特定の数値型を別の数値型に変換するには、既存の値で希望する型の新しい数値を初期化

```swift
let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
let twoThousandAndOne = twoThousand + UInt16(one)
```

SomeType(ofInitialValue)

- Swift の型のイニシャライザーを呼び出す、初期値を渡すデフォルトの方法
- 裏では、UInt16 は UInt8 値を受け入れるイニシャライザを持っている
    - このイニシャライザは既存の UInt8 から新しい UInt16 を作るために使用
    - UInt16がイニシャライザを提供する型でなければ使用できない
- 新しい型（独自の型定義を含む）を受け入れるイニシャライザを提供するために既存の型を拡張可能

## 整数と浮動小数点の変換

```swift
// 整数型と浮動小数点数値型の変換は明示的に行う必要がある
let three = 3
let pointOneFourOneFiveNine = 0.14159
let pi = Double(three) + pointOneFourOneFiveNine
// 3.14159

// 浮動小数点から整数への変換も明示的に行う必要がある
// この方法で新しい整数値を初期化する場合、浮動小数点値は常に切り捨てられる
let integerPi = Int(pi)
// 3
```

# 型エイリアス

型エイリアスは、既存の型の代替名を定義

- typealias キーワードで定義

型エイリアスは、既存の型をより文脈に適した名前で参照したい場合に便利

- 外部ソースから特定のサイズのデータを扱う場合など

```swift
typealias AudioSample = UInt16
var maxAmplitudeFound = AudioSample.min
// 0
```

# 真偽値

基本的なブール型

- Bool
- ブール値は論理値と呼ばれる
    - 真か偽にしかならないため
- ブール定数値
    - true
    - false

```swift
let orangesAreOrange = true
let turnipsAreDelicious = false
```

ブール値は、if文のような条件文を扱うときに特に便利

```swift
let turnipsAreDelicious = false
if turnipsAreDelicious {
    print("Mmm, tasty turnips!")
} else {
    print("Eww, turnips are horrible.")
    // Eww, turnips are horrible.
}
```

# タプル

タプル

- 複数の値を1つの複合値にグループ化
- 値はどのような型でもよく、互いに同じ型である必要はない
- 中身を個別の定数や変数に分解することができ、通常通りアクセスすることが可能
- 0から始まるインデックス番号を使って、タプル内の個々の要素値にアクセスすることも

```swift
let http404Error = (404, "Not Found")
let (statusCode, statusMessage) = http404Error
print("The status code is \(statusCode)")
// The status code is 404
print("The status message is \(statusMessage)")
// The status message is Not Found
print("The status code is \(http404Error.0)")
// The status code is 404
print("The status message is \(http404Error.1)")
// The status message is Not Found
```

タプルの定義時に、タプル内の個々の要素に名前を付けることも可能

```swift
let http200Status = (statusCode: 200, description: "OK")
print("The status code is \(http200Status.statusCode)")
// The status code is 200
print("The status message is \(http200Status.description)")
// The status message is OK
```

タプルは関数の戻り値として特に有用

## 注記

- タプルは、関連する値の単純なグループに便利
- **複雑なデータ構造の作成には向いていない**
- データ構造が複雑になりそうな場合は、タプルではなくクラスや構造体としてモデル化

# オプショナル

オプショナルは、値が存在しない可能性のある状況で使用

オプショナルは2つの可能性を示す

- 指定された型の値が存在し、その値にアクセスするためにオプショナルをアンラップ可能
- 値がまったく存在しない

```swift
let possibleNumber = "123"
let convertedNumber: Int? = Int(possibleNumber)
// イニシャライザーは失敗する可能性があるため、IntではなくオプショナルのInt
```

オプショナル型の記述方法

- オプショナルが含む型名の後にクエスチョンマーク（?）
- オプショナルのInt型
    - 常に何らかのInt値を含む
    - まったく値を含まない

## nil

オプショナル変数に特別な値nilを代入して、値を持たない状態にする

```swift
var serverResponseCode: Int? = 404
serverResponseCode = nil
```

デフォルト値を指定せずにオプショナル変数を定義すると、その変数は自動的にnilに設定

```swift
var surveyAnswer: String?
// nil
```

if 文を使用して、オプショナルに値が含まれているかどうかを調べるには、オプショナルと nil を比較

- 比較には、"等しい" 演算子 (==) または "等しくない" 演算子 (!=) を使用

```swift
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)

if convertedNumber != nil {
    print("convertedNumber contains some integer value.")
    // convertedNumber contains some integer value.
}
```

オプショナルでない定数や変数にnilを使うことはできない

- 非オプショナル値として宣言された定数や変数は、決してnil値を含まないことを保証
- オプショナルでない値にnilを代入しようとすると、コンパイル時にエラーが発生

コード内の定数や変数が、特定の条件下で値がない場合に動作する必要がある場合は、適切な型のオプショナルとして宣言

オプショナル値と非オプショナル値を分ける理由

- どのような情報が欠落してもよいかを明示的に示すことが可能
- 欠落した値を扱うコードが書きやすくなる
- 値をアンラップした後は、その値を扱う他のどのコードも nil をチェックする必要がない
    - コードのさまざまな部分で同じ値を繰り返しチェックする必要がなくなる

オプショナル値にアクセスする場合

- コードでは常に nil と non-nil の両方のケースを扱う

値が欠落しているときにできること

- nilのときに値を操作するコードをスキップ
- nilを返すか?演算子を使用
- ??演算子を使用して、フォールバック値を指定
- !演算子を使用して、プログラムの実行を停止

### 注記

- nil はポインタではない
- 特定の型の値の不在
- オブジェクト型だけでなく、どの型のオプションもnilに設定可能

## ****オプショナルバインディング****

オプショナル・バインディング

- オプショナルに値が含まれているかどうかを調べる
- 含まれていればその値を一時的な定数や変数として利用できるようにするために使用
- if文、guard文、while文と一緒に使用

```swift
let possibleNumber = "123"
if let actualNumber = Int(possibleNumber) {
    print("The string \"\(possibleNumber)\" has an integer value of \(actualNumber)")
    // The string "123" has an integer value of 123
} else {
    print("The string \"\(possibleNumber)\" couldn't be converted to an integer")
}
```

元の定数や変数に含まれる値にアクセスした後に、元の定数や変数を参照する必要がない場合

- 新しい定数や変数に同じ名前を使用可能

```swift
let possibleNumber = "123"
let myNumber = Int(possibleNumber)
if let myNumber = myNumber {
    print("My number is \(myNumber)")
    // My number is 123
}

if let myNumber {
    print("My number is \(myNumber)")
    // My number is 123
}
```

オプショナル・バインディング

- 定数と変数の両方を使用可能
- if文の内部で加えた変更は、そのローカル変数にのみ適用
    - ラップを解除した元のオプショナル定数や変数には適用されない

```swift
var value = Int("10")
print(value)
// Optional(10)
if var value {
    print(value)
    // 10
    value = 20
    print(value)
    // 20
}
print(value)
// Optional(10)
```

1つのif文には、オプションのバインディングとブール条件をカンマ区切りで必要なだけ含めることが可能

- if文全体の条件がfalseとみなされる場合
    - オプショナル・バインディングの値のいずれかがnil
    - ブール条件がfalse

```swift
// 以下のコードは同等
if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 {
    print("\(firstNumber) < \(secondNumber) < 100")
    // 4 < 42 < 100
}

if let firstNumber = Int("4") {
    if let secondNumber = Int("42") {
        if firstNumber < secondNumber && secondNumber < 100 {
            print("\(firstNumber) < \(secondNumber) < 100")
            // 4 < 42 < 100
        }
    }
}
```

if文のオプショナル・バインディングで作成された定数や変数

- if文のボディ内でのみ使用可能

一方、guard文で作成された定数や変数

- guard文に続くコード行で使用可能

## フォールバック値の提供

欠落値を扱うもうひとつの方法は、nil-coalescing演算子（??）

- ??の左側のオプショナルがnilでなければ、その値がアンラップされて使われる
- それ以外の場合は、??の右側の値が使われれる

```swift
let name: String? = nil
let greeting = "Hello, " + (name ?? "friend") + "!"
print(greeting)
// Hello, friend!
```

## フォース・アンラッピング

nil がプログラマのエラーや破損した状態のような回復不可能な失敗を表す場合

- オプショナルの名前の最後に感嘆符 (!) を追加
- 基礎となる値にアクセスすることが可能
- オプショナルの値を強制的にアンラップすること
- nilでない値を強制的にアンラップすると、その結果はアンラップされた値となる
- nil 値を強制アンラップすると、実行時エラーが発生

```swift
let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)

// 下記のコードのどちらもconvertedNumberが常に値を含むことに依存
// この要件をコードの一部として記述することで、
// 上記のどちらかのアプローチを使用して、実行時に要件が真であることをチェックすることが可能

let number = convertedNumber!
print(number)
// 123

guard let number = convertedNumber else {
    fatalError("The number was invalid")
}
print(number)
// 123
```

## 暗黙的にアンラップされたオプション

オプショナル

- 定数や変数に「値がない」ことが許されていること示す
- 値が存在するかどうかを if 文でチェックすることが可能
- 値が存在する場合
    - オプショナル・バインディングで条件付きでアンラップ
    - オプショナルの値にアクセス可能

プログラムの構造上、オプショナルが最初に設定された値を必ず持つことが明らかな場合

- オプショナルにアクセスするたびにその値をチェックしたりラップを解除したりする必要がなくなると便利
- 暗黙的にアンラップされたオプショナルとして定義可能
    - オプショナルにしたい型の後にクエスチョンマーク(String?)ではなく感嘆符(String!)を置く
    - オプショナルを使用するときにオプショナルの名前の後に感嘆符を置くのではない
    - オプショナルを宣言するときにオプショナルの型の後に感嘆符を置く

暗黙的にアンラップされたオプショナル

- オプショナルが最初に定義された直後にオプショナルの値が存在することを確認
- その後のすべての時点で確実に存在すると仮定できる場合に便利

Swift での暗黙的にラップされていないオプションの主な使用は、クラスの初期化の間

後で変数がnilになる可能性がある場合

- 暗黙的にアンラップされたオプショナルを使用しない

変数の有効期間中にnil値をチェックする必要がある場合

- 常に通常のオプショナル型を使用

暗黙的にアンラップされたオプショナル

- 裏では通常のオプショナル
- アクセスするたびにオプショナル値をアンラップする必要がない
    - 非オプショナル値のように使用可能

```swift
// オプショナル文字列と、暗黙のうちにアンラップされたオプショナル文字列とが、
// 明示的な String としてラップされた値にアクセスする際の動作の違い

let possibleString: String? = "An optional string."
let forcedString: String = possibleString!
// 明示的なアンラッピングが必要

let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString
// 自動でアンラッピング
```

暗黙的にアンラップされたオプショナルは、必要であれば強制的にアンラップされることを許可していると考えることが可能

暗黙的にアンラップされたオプショナルが nilの場合

- ラップされた値にアクセスしようとすると、実行時エラーが発生
- この結果は、値を含まない通常のオプショナルを強制的にアンラップするために感嘆符を書いた場合と同じ

暗黙的にアンラップされたオプショナルをオプショナル・バインディングで使用すると、1つのステートメントでその値をチェックし、アンラップすることが可能

```swift
let assumedString: String! = "An implicitly unwrapped optional string."
if let definiteString = assumedString {
    print(definiteString)
}
```

# エラー処理

エラー処理は、プログラムが実行中に遭遇する可能性のあるエラー状態に対応するために使用

- 値の有無で関数の成否を伝えるオプショナルとは対照的
- エラー処理では失敗の根本的な原因を突き止め、必要であればプログラムの別の部分にエラーを伝搬

関数がエラー状態に遭遇すると、エラーをスロー

- その関数の呼び出し元は、エラーをキャッチして適切に応答可能

```swift
func canThrowAnError() throws {
    // この関数はエラーを投げるかもしれないし、投げないかもしれない。
}
```

関数は、その宣言にthrowsキーワードを含めることで、エラーを投げることができることを示す

- エラーを投げることができる関数を呼び出すときは、try キーワードを式の前につける
- catch 節によって処理されるまで、自動的に現在のスコープの外にエラーを伝播

```swift
func canThrowAnError() throws {
    // この関数はエラーを投げるかもしれないし、投げないかもしれない。
}

// ここから
do {
    try canThrowAnError()
    // エラーは発生しなかった
} catch {
    // エラーがスローされた
}
```

do文は新しい包含スコープを作り、エラーを1つ以上のcatch句に伝搬

```swift
func makeASandwich() throws {
    // ...
}

do {
    try makeASandwich()
    eatASandwich()
} catch SandwichError.outOfCleanDishes {
    washDishes()
} catch SandwichError.missingIngredients(let ingredients) {
    buyGroceries(ingredients)
}
```

# アサーションと前提条件

アサーションと前提条件は、実行時に行われるチェック

- これ以降のコードを実行する前に、必須条件が満たされていることを確認するために使用
- アサーションや前提条件のブール条件が真と評価されれば、コードの実行は通常通り続行
- その条件が false と評価されると、プログラムの現在の状態は無効となり、コードの実行は終了してアプリは終了

アサーションと前提条件は、コーディング中の仮定や期待値を表現するために使用

アサーション

- **開発中に間違いや間違った仮定を見つけるのに役立つ**

前提条件

- **本番環境で問題を検出するのに役立つ**

アサーションと前提条件は、実行時の期待値を検証するだけでなく、 コード内のドキュメント化にも役立つ

エラー条件とは異なり、 アサーションや前提条件は回復可能なエラーや期待されるエラーには使用されない

失敗したアサーションや前提条件は無効なプログラム状態を示す

- 失敗したアサーションをキャッチする方法はない
- 無効な状態から回復することは不可能
- アサーションが失敗すると、プログラムのデータの少なくとも1つが無効

アサーションや前提条件の使用は、無効な状態が発生しにくいようにコードを設計することの代わりにはならない
しかし、有効なデータと状態を強制するためにこれらを使用することで、無効な状態が発生した場合にアプリがより予測可能な形で終了するようになり、問題のデバッグが容易となる

- 仮定がチェックされない場合、この種の問題に気づくのは、他の場所でコードが目に見えて失敗し始め、ユーザーデータが静かに破損したずっと後になってからかもしれない
- 無効な状態が検出されたらすぐに実行を停止することも、その無効な状態によるダメージを抑えるのに役立つ

アサーションと前提条件の違いは、チェックされるタイミング

- アサーションはデバッグビルドでのみチェック
    - 実運用ビルドでは、アサーション内の条件は評価されない
    - 開発プロセスではアサーションをいくつでも使用することが可能
    - 実運用ビルドではパフォーマンスに影響を与えない
- 前提条件はデバッグビルドと本番ビルドの両方でチェック

## アサーションを使ったデバッグ

標準ライブラリから assert(_:_:file:line:) 関数を呼び出してアサーションを記述

- 引数
    - true または false と評価される式
    - 条件の結果が false の場合に表示するメッセージ

```swift
let age = -3
assert(age >= 0, "A person's age can't be less than zero.")
// Assertion failed: A person's age can't be less than zero.
```

アサーション・メッセージを省略も可能

```swift
let age = -3
assert(age >= 0)
// Assertion failed
```

コードがすでに条件をチェックしている場合は、アサーションが失敗したことを示すために assertionFailure(_:file:line:) 関数を使用

```swift
let age = -3
if age > 10 {
    print("You can ride the roller-coaster or the ferris wheel.")
} else if age >= 0 {
    print("You can ride the ferris wheel.")
} else {
    assertionFailure("A person's age can't be less than zero.")
    // Fatal error: A person's age can't be less than zero.
}
```

## 前提条件の強制

**ある条件が偽になる可能性があるが、コードの実行を続行するためには絶対に真でなければならない場合は、必ず前提条件を使用**

- 添え字が範囲外でないことをチェック
- 関数に有効な値が渡されたことをチェック

precondition(*:*:file:line:) 関数を呼び出して前提条件を記述

- 引数
    - trueまたはfalseと評価される式
    - 条件の結果がfalseの場合に表示するメッセージ

```swift
precondition(index > 0, "Index must be greater than zero.")
```

preconditionFailure(_:file:line:)関数を呼び出すことで、失敗が発生したことを示すことも可能

- スイッチのデフォルト・ケースが取られたが、有効な入力データはすべてスイッチの他のケースで処理されるはずだった場合

### 注記

uncheckedモード（-Ounchecked）でコンパイルすると、前提条件はチェックされない

- コンパイラーは前提条件が常に真であると仮定し、それに応じてコードを最適化
- fatalError(_:file:line:)関数は、最適化の設定に関係なく、常に実行を停止

**スタブの実装としてfatalError("Unimplemented")と書くことによって、プロトタイピングや開発の初期段階において、まだ実装されていない機能のスタブを作成するために使用**

- fatalError(_:file:line:)関数は、アサーションや前提条件とは異なり、最適化されることがない
- スタブ実装に遭遇した場合、常に実行が停止することを確認することが可能

# 参考

[Documentation](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/thebasics/)