[解決済み] Swiftのthrowとrethrowsの違いは何ですか?
質問
いくつかの文献を検索してみたのですが、残念ながら
throws
と
rethrows
. これらの使い分けを理解しようとすると、ちょっと混乱します。
私は -default- の使い方に慣れていることを述べておきます。
throws
を、エラーを伝播させるための最も単純な形として、以下のように記述します。
enum CustomError: Error {
case potato
case tomato
}
func throwCustomError(_ string: String) throws {
if string.lowercased().trimmingCharacters(in: .whitespaces) == "potato" {
throw CustomError.potato
}
if string.lowercased().trimmingCharacters(in: .whitespaces) == "tomato" {
throw CustomError.tomato
}
}
do {
try throwCustomError("potato")
} catch let error as CustomError {
switch error {
case .potato:
print("potatos catched") // potatos catched
case .tomato:
print("tomato catched")
}
}
ここまではいいのですが、問題は次のときです。
func throwCustomError(function:(String) throws -> ()) throws {
try function("throws string")
}
func rethrowCustomError(function:(String) throws -> ()) rethrows {
try function("rethrows string")
}
rethrowCustomError { string in
print(string) // rethrows string
}
try throwCustomError { string in
print(string) // throws string
}
という関数を呼び出すと、その関数の中で
throws
で処理されなければならないことです。
try
とは異なり
rethrows
. だから何なんだ!?を使うかどうかを決めるときに従うべき論理は何でしょうか?
throws
あるいは
rethrows
?
どのように解決するのですか?
から "宣言" をSwiftの本で見てみましょう。
関数とメソッドの再投入
関数やメソッドは
rethrows
キーワードで宣言することができます。 関数のパラメータがエラーを投げるときだけエラーを投げることを示すために パラメータがエラーを投げる場合のみエラーを投げることを示します。これらの関数やメソッドは 再投げ関数 と呼ばれ メソッドの再投入 . 再投げ関数と メソッドは少なくとも一つのスローイングファンクションパラメータを持っていなければなりません。
典型的な例としては
map
メソッドです。
public func map<T>(_ transform: (Element) throws -> T) rethrows -> [T]
もし
map
がスローしないトランスフォームで呼ばれた場合、それ自身はエラーをスローしません。
を投げないので
try
:
// Example 1:
let a = [1, 2, 3]
func f1(n: Int) -> Int {
return n * n
}
let a1 = a.map(f1)
しかし、もし
map
がスローするクロージャで呼ばれた場合は、それ自体がスローする可能性があります。
で呼び出されなければなりません。
try
:
// Example 2:
let a = [1, 2, 3]
enum CustomError: Error {
case illegalArgument
}
func f2(n: Int) throws -> Int {
guard n >= 0 else {
throw CustomError.illegalArgument
}
return n*n
}
do {
let a2 = try a.map(f2)
} catch {
// ...
}
-
もし
map
と宣言された場合throws
ではなくrethrows
というように で呼び出さなければなりません。try
で呼び出さなければなりません。 これは不便であり、コードを不必要に肥大化させます。 -
もし
map
がない状態で宣言された場合throws/rethrows
がない場合は、例2のように で宣言されている場合は、例2のようにスローイングクロージャで呼び出すことはできません。
同じことが、Swift 標準ライブラリの他のメソッドにも当てはまります。
の他のメソッドも同様です。
filter()
,
index(where:)
,
forEach()
などなど。
あなたの場合
func throwCustomError(function:(String) throws -> ()) throws
は、エラーを投げない引数で呼ばれてもエラーを投げることができる関数を表します。 投げない引数で呼ばれてもエラーを投げる可能性がある関数を表します。
func rethrowCustomError(function:(String) throws -> ()) rethrows
を付けて呼ばれた場合のみエラーを投げる関数を表します。 を投げる引数で呼ばれた場合のみエラーを投げる関数を表します。
大雑把に言うと
rethrows
は、エラーを投げない関数のためのものです。
エラーを投げるのではなく、関数のパラメータからエラーを転送するだけです。
パラメータからエラーを転送するだけです。
関連
-
[解決済み] Swiftのstatic funcとclass funcの違いは何ですか?
-
[解決済み] Swift言語におけるエクスクラメーションマークの意味とは?
-
[解決済み] Swiftでindexとelementでループを反復させる方法
-
[解決済み】プログラムを停止/終了させることなく、完全な例外トレースバックをキャッチして表示する方法は?
-
[解決済み】 `throw new Error` と `throw someObject` の違いは何ですか?
-
[解決済み】なぜ、Swiftの文字列では、?のような絵文字が奇妙に扱われるのですか?
-
[解決済み】Swiftの`let`と`var`の違いは何ですか?
-
[解決済み] Swiftのdo-try-catch構文
-
[解決済み] UIViewの定高制約をプログラムで更新するには?
-
[解決済み] Swift- Remove Push Notification Badge number?
最新
-
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ダブルからストリング
-
[解決済み] Swift 3でカスタム通知を作成するには?
-
[解決済み] Swiftのリバースレンジ
-
[解決済み] Swiftで範囲を作成する方法は?
-
[解決済み] アニメーションによる円の描画
-
[解決済み] Swift で UIViewController のサブクラス用のカスタムイニシャライザを作るには?
-
[解決済み] Swift - サブクラスでオーバーライドする必要があるクラスメソッド
-
[解決済み] SwiftでNSDatesの秒数の差を整数値で求める。
-
[解決済み] iOS 9のスワイプ可能なテーブルビューセル
-
[解決済み] 弱い自分はどこへ行くのか?