[解決済み] Swiftのdo-try-catch構文
質問
swift 2の新しいエラー処理について理解するために試してみました。以下は、私が行ったことです。私は最初にエラー列挙型を宣言しました。
enum SandwichError: ErrorType {
case NotMe
case DoItYourself
}
そして、エラー(例外ではありません。エラーです)を投げるメソッドを宣言しました。以下がそのメソッドです。
func makeMeSandwich(names: [String: String]) throws -> String {
guard let sandwich = names["sandwich"] else {
throw SandwichError.NotMe
}
return sandwich
}
問題は呼び出し側からです。以下は、このメソッドを呼び出すコードです。
let kitchen = ["sandwich": "ready", "breakfeast": "not ready"]
do {
let sandwich = try makeMeSandwich(kitchen)
print("i eat it \(sandwich)")
} catch SandwichError.NotMe {
print("Not me error")
} catch SandwichError.DoItYourself {
print("do it error")
}
の後に
do
行のコンパイラは
Errors thrown from here are not handled because the enclosing catch is not exhaustive
. しかし、私の意見では、これは網羅的なものです。
SandwichError
の列挙です。
通常のswitch文の場合、すべてのケースを処理すると網羅的であると理解できます。
どのように解決するのですか?
Swift 2のエラー処理モデルには、「網羅性」と「回復力」という2つの重要なポイントがあります。一緒に、それらはあなたの
do
/
catch
文は、投げることができるとわかっているエラーだけでなく、起こりうるすべてのエラーをキャッチする必要があります。
関数が投げることができるエラーの種類を宣言していないこと、そして、全く投げることができないかどうかだけを宣言していることに注意してください。これは一種のゼロ・ワン・イン・フィニティの問題で、他の人(将来の自分も含めて)が使う関数を定義する者として、関数の実装が変更されるたびに、その関数のすべてのクライアントを適応させる必要はないでしょう(どのエラーを投げることができるかも含めて)。関数を呼び出すコードは、そのような変化に強いものであってほしいのです。
この関数は、どのようなエラーを投げるか (あるいは将来投げる可能性があるか) を知ることができないので
catch
ブロックは、どのような種類のエラーを投げるかを知りません。そこで、自分が知っているエラーの種類を処理するだけでなく、 知らないエラーの種類を処理するために、普遍的な
catch
そうすれば、将来この関数が投げるエラーのセットを変更したとしても、 呼び出し元はそのエラーを捕捉することができます。
do {
let sandwich = try makeMeSandwich(kitchen)
print("i eat it \(sandwich)")
} catch SandwichError.NotMe {
print("Not me error")
} catch SandwichError.DoItYourself {
print("do it error")
} catch let error {
print(error.localizedDescription)
}
しかし、そこで終わりではない。このレジリエンス(回復力)の考え方をもう少し考えてみましょう。あなたが設計したサンドイッチの方法では、エラーを使うすべての場所でエラーを記述しなければなりません。つまり、エラーケースのセットを変更するたびに、それを使っているすべての場所を変更しなければならないのです...あまり楽しいことではありませんね。
独自のエラータイプを定義することで、そのようなことを一元管理できるようにするのが狙いです。例えば
description
メソッドを使用します。
extension SandwichError: CustomStringConvertible {
var description: String {
switch self {
case NotMe: return "Not me error"
case DoItYourself: return "Try sudo"
}
}
}
そして、エラー処理のコードは、エラータイプに自分自身を記述するように求めることができます。これで、エラーを処理するすべての場所で同じコードを使用でき、将来起こりうるエラーケースも処理できるようになります。
do {
let sandwich = try makeMeSandwich(kitchen)
print("i eat it \(sandwich)")
} catch let error as SandwichError {
print(error.description)
} catch {
print("i dunno")
}
これはまた、エラータイプ (あるいはその拡張) が他のエラー報告方法をサポートする道を開くものでもあります。
UIAlertController
iOSのユーザーにエラーを報告するためのものです。
関連
-
[解決済み] スウィフト 2: !, ?-" オプション型「...」の値がアンラップされていない"
-
[解決済み] 型の不変値に変異型メンバを使用することはできません。
-
[解決済み] Fatal error.とは何ですか?Unexpectedly found nil while unwrapping an Optional value" とはどういう意味ですか?
-
[解決済み] swiftの"? "の意味は何ですか?[重複している]。
-
[解決済み] SwiftからObjective-Cのコードを呼び出すにはどうしたらいいですか?
-
[解決済み] Swiftで#pragmaマーク?
-
[解決済み] Swift Betaのパフォーマンス:配列のソート
-
[解決済み] Swiftベースのアプリケーションは、OS X 10.9/iOS 7以下でも動作しますか?
-
[解決済み】Swift - StringをDoubleに変換する方法
-
[解決済み】コンパイラーエラー。Objective-C のセレクタを持つメソッドは、同じ Objective-C セレクタを持つ以前の宣言と競合しています。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Swift 5でXOR?
-
[解決済み] Swift 3でdispatch_onceはどうなる?
-
[解決済み] SwiftでString.Indexはどのように動作するのか
-
[解決済み] なぜ「Implicitly Unwrapped Optionals」を作るのか、それは値があることを知っていることを意味しているからです。
-
[解決済み] Swiftで乱数を生成する方法とは?
-
[解決済み】weak referenceとunowned referenceの違いは何ですか?
-
[解決済み】Swiftでボタンに丸みを帯びたボーダーを付けるにはどうすればいいですか?
-
[解決済み】プログラムによってナビゲーションのタイトルを変更する
-
[解決済み】UIViewControllerの最上位機種を取得する。
-
[解決済み] 非同期ネットワークリクエストのswift forループの実行が終了するまで待つ