この記事は何?
Swiftプログラミングでのエラー処理について、調べました。
忘備録を兼ねて投稿します。
参考記事: Swift Language Guide
実行環境
Swift5.x
Xcode11 beta2
macOS 10.14 Mojave
ハンズオン
エラーを__定義して、スローする__プログラムを記述します。
こんなクラスがあったとして
自動販売機をコードで表現しています。
// 商品の金額と残り個数
struct ItemInfo {
var price: Int
var count: Int
}
// 自動販売機
class VendingMachine {
var inventories = [String: ItemInfo]() // 在庫の商品
var coinsDeposited = 0 // 預かり金
// 商品を販売
func vend(itemNamed name: String) {
let selectedItem = inventories[name]
coinsDeposited -= selectedItem.price
var newItem = selectedItem
newItem.count -= 1
inventories[name] = newItem // updating a value
print("Dispensing \(name)")
}
}
自販機のインスタンス
自動販売機のインスタンス drinkStand
を生成して、"Coke"
を買います。
let drinkStand = VendingMachine()
// ドリンクを補填
drinkStand.inventories = [
"Coke" : ItemInfo(price: 120, count: 7),
"Soda" : ItemInfo(price: 80, count: 3),
"Milk" : ItemInfo(price: 100, count: 10)]
// コーラを買う
drinkStand.vend(itemNamed: "Coke")
起こりうるエラー
この自販機プログラムでは、以下のようなエラーが発生するかもしれません。
- 無効な商品を選択
- 支払額が不足
- 在庫なし
自販機で起こりうるエラー を列挙型を使って、コードで定義します。
このとき、Error
プロトコルに準拠させておくと、Swiftが自動的にエラーハンドリングの対象にしてくれます。
enum VendingMachineError: Error {
case invalidSelection // 無効な選択
case insufficientFunds(coinsNeeded: Int) // 支払額が不足
case outOfStock // 在庫なし
}
Error プロトコル
具体的な実装はなく、カラのプロトコルです。
準拠に適合するために、何か特別なことをする必要はありません。
エラーをthrow(スロー)する
自販機クラス内のエラーが発生しそうな行で、エラーをスロー します。
throw
キーワードを使います。
どんなエラーが発生したかは、VendingMachineError
型を使って指定できます。
この時点で、vend(itemNamed:)
メソッドはエラーを throw
するかもしれないメソッドになりました。
メソッド宣言のパラメータ直後に throws
キーワードを記述します。
class VendingMachine {
var inventories = [String: ItemInfo]()
var coinsDeposited = 0
func vend(itemNamed name: String) throws {
// 無効な商品を選択したら、エラーをスローする
guard let selectedItem = inventories[name] else {
throw VendingMachineError.invalidSelection
}
coinsDeposited -= selectedItem.price
var newItem = selectedItem
newItem.count -= 1
inventories[name] = newItem
print("Dispensing \(name)")
}
}
エラーをスローする関数の定義
throw
キーワードと throws
キーワードは間違いやすいので、気をつける必要があります。
// エラーをスローできる関数の宣言
func canThrowErrorsMethod() throws -> <ReturnType>
// エラーをスローしない関数の宣言
func cannotThrowErrorsMethod() -> <ReturnType>