今回から The Basics
の Error Handling
について眺めていきます。前回のオプショナルに続いて Swift の大事なコンセプトにある安全性を支える機能のひとつで、扱う機会もそれなりに多いものと思うので、この機にその基礎的なところをおさらいしてみましょう。よろしくお願いしますね。
今回は参加者の一般公募もされていまして、ゆめみ社外な人の参加されての開催になります。
————————————————————————————————— 熊谷さんのやさしい Swift 勉強会 #179
00:00 開始 01:34 実行時に遭遇するかもしれないエラーに対応 02:59 エラーの原因を特定する手段を提供 04:06 失敗の原因特定と移譲 06:21 一般的な例外処理とは違った言語構文 09:02 エラーが発生するかもしれない箇所が明瞭 10:55 エラーを送出するかもしれない関数 11:27 エラーハンドリングの仕組みのおさらい 12:39 エラーの伝え方について 14:53 オプショナルな Void で、実行できたか判定する 17:42 Void? の効能を知っておけば使い道も見つかるかも? 18:44 セッターの呼び出し確認に Void? を使う 22:10 代入されるのが確かな場合と不確かな場合 24:40 Void? の使い道を知っておくことは大事 26:32 Void? 判定は見慣れる必要があるかもしれない 26:53 ヨーダ記法が不要な言語仕様 28:07 知っているとコードが明瞭になる 30:11 Void? による判定は、一般に受け入れられるもの? 30:43 クロージングと次回の展望 —————————————————————————————————
Transcription & Summarize : 熊谷さんのやさしい Swift 勉強会 #179
さて、勉強会を始めていきましょう。今日は「The Basics」のエラーハンドリングについてです。日本語訳として、今スライドに映っている通り「エラー処理」と訳してみました。
Swiftのエラー処理には、いわゆるエラーハンドリングのほかにもオプショナル、致命的エラー、そしてプレコンディションなどがあります。大きくひっくるめると、エラー処理にはさまざまな手法がありますので、「エラーハンドリング」と訳したほうが語弊がないかもしれません。とりあえず「エラー処理」と訳した感じで進めてみますが、語弊があった場合は適宜訂正します。
この解説は私が勝手に訳しているだけなので、公式な日本語訳ではありません。しかし、公式のSwiftプログラミング言語にはどのような言葉が使われているのかを見ていくと、実行時に遭遇する可能性のあるエラーの状況に対応するためにエラーハンドリングを用いるという記述があります。自分が翻訳をしていながらも、やはり「エラーハンドリング」という用語が適切です。
エラー処理というと、実行時に限らないですよね。コンパイルタイムにエラーが発生する可能性を考慮することもありますが、エラーハンドリングについては、少なくとも現時点では実行時に対応するものです。将来的にコンパイルタイムにエラーハンドリングができるようになるかは分かりませんが、今のところは実行時のエラーに対する対応が重要です。
他にも、エラーハンドリングにはオプショナルを使って関数の戻り値を表現する方法があります。オプショナルは失敗の原因を細かく特定するのではなく、存在有無だけを示すのに対して、エラーハンドリングは失敗の原因を特定し、必要に応じてエラーを別の部分に移動することができるという違いがあります。
オプショナルもある意味でエラー処理の一環として機能している点では似た性格を持っているかもしれませんが、エラーハンドリングのアプローチは、より具体的なエラーの追跡や処理ができる点が特徴です。 もちろん、文字起こしテキストをこちらに貼り付けていただければ、それを自然な文章に整えます。テキストをお待ちしています。 この辺りの話題については、どこまで深掘りするかや、感覚的な違いなどもありますので、ここで一旦区切りたいと思います。興味深い特徴としてエラーハンドリングがありますね。Swiftのエラーハンドリングについて、Playgroundで実際に見ていきましょう。
具体的にはエラーハンドリングの失敗の原因を特定し、必要ならそのエラーを別の部分に移動させることができます。ただ、言葉だけではよく理解できないかと思いますので、コードを見ながら説明しますね。
エラーハンドリングの基本としては、Swiftではdo-catch
ブロックを使用して、その中でエラーハンドリングを行います。例えば、このブロック内でエラーが発生する可能性がある関数を呼び出し、エラーが発生した場合にはcatch
ブロックでそのエラーを処理します。
例えば、以下のようなコードがあります:
do {
try someFunction()
} catch {
print("An error occurred: \\(error)")
}
このように、try
キーワードを使って関数を呼び出し、その後catch
ブロックでエラーを受け取って対応します。この例では、3行目でエラーが発生した場合、4行目のcatch
ブロックでそのエラーを処理します。
一般的なプログラミング言語では、エラー処理を「例外処理(exception handling)」と呼ぶことが多いですが、Swiftでは「エラーハンドリング」として実装されています。Swiftでは、エラーを発生させる可能性がある関数を呼び出すために、try
キーワードを明示的に使用します。
例えば、以下のようにtry
を使わずに関数を呼び出すと、その関数がエラーを発生させるかどうかわからないため、コンパイラが警告を出します:
func someFunction() throws {
// エラーを発生させる可能性がある処理
}
do {
try someFunction()
} catch {
print("An error occurred: \\(error)")
}
このようなコードを書くことで、Swiftでは関数がエラーを発生させる可能性があるかどうかを明示的に示すことができます。
エラーが発生するかもしれない関数は「スローイング関数」と呼ばれ、throws
キーワードを使用して定義されます。また、try
キーワードを使用してその関数を呼び出すことで、エラーハンドリングのメカニズムが有効になります。これにより、プログラマーやコンパイラがどこでエラーが発生する可能性があるのかを把握しやすくなります。
以上のように、Swiftのエラーハンドリングは、他の言語の例外処理と似ていますが、エラーが発生する場所を明示的に示す点で非常に優れていると言えます。これによって、コードをレビューする際にもどこでエラーが発生し得るのかを容易に理解することができます。 エラー処理のとても大きな特徴として、エラーを返すときに失敗の原因を特定できるようにすることがあります。これはエラーハンドリングの基本的な考え方です。JavaやJavaScriptでは、エラーメッセージは伝えられるものの、原因が明確に伝えられないことが多いです。例えば、エラーメッセージが「エラーが起きたよ」と言うだけなら、それ以上の詳細な情報が得られないことがあります。
そのため、エラー処理には、なぜ失敗したのかを明確にするための情報が重要です。Swiftでは、オプショナル (Optional
) を活用することができます。特にリターンが Void
型の場合でも、オプショナルを使うことで失敗の有無を判断できるようになります。例えば、以下のようなコードが考えられます。
func performAction() -> Void? {
// 何らかの処理
return nil // 失敗の場合
}
この場合、 performAction
関数が nil
を返す場合は、処理が失敗したことを意味します。このように Optional
を活用すると、実行結果を直接的に確認でき、エラーハンドリングが簡素化されます。
次に、オプショナルバインディング (Optional Binding
) を使用することで、更に明確なエラーハンドリングが可能です。例えば、以下のようなコードがあります。
let optionalString: String? = nil
if let actualString = optionalString {
print(actualString)
} else {
print("optionalString is nil")
}
このコードでは、 optionalString
が nil かどうかを判定し、 nil でない場合のみ print
文を実行します。これにより、 optionalString
が nil である場合の対処も明確に示すことができます。
また、プレイグラウンド上での代入式も興味深い点があります。例えば、以下のような代入式があります。
var a: String? = "hello"
a = nil
この場合、代入式自体が Void
型を返すため、その代入が成功したかどうかを判断する基準として nil
を利用することができます。ただし、 nil
を検出するためにはオプショナルの利用が必須となります。
まとめると、Swiftにおけるエラーハンドリングやオプショナルの利用方法を理解することで、エラーハンドリングの精度と明確さが向上します。したがって、エラーの原因を特定できる情報を適切に活用し、効率的なプログラムを書くための手法としてオプショナルを効果的に利用することが重要です。 はい、プログラミングの話を続けましょう。
Swiftでは、オプショナルチェーニングを使うことで、安全にプロパティへのアクセスを試みることができます。たとえば、person.residence?.address
のように書くと、residence
が nil
であった場合でも address
にアクセスしようとしてクラッシュすることを防げます。
コード例として、次のような構造があるとします。
class Person {
var residence: Residence?
}
class Residence {
var address: String?
}
let person = Person()
person.residence?.address = "123 Main St"
このように、オプショナルチェーニングを使って安全にアクセスできます。また、person
が nil
でもクラッシュしません。
また、Swiftの言語仕様では、変数の初期代入時に必ず値が設定されることが保証されます。これは他のプログラミング言語からの移行には重要な点です。特に、C言語やC++などではポインタの安全性が保証されていないため、クラッシュを避けるために大量のチェックコードを書かなければならないことが多々あります。
オプショナルチェーニングや強制アンラップ(!
)についても触れると、後者は避けるべきケースが多いです。強制アンラップはnil値が存在する場合にクラッシュを引き起こし、そのためSwiftの安全性の理念に反するためです。
最後に、次回の勉強会ではエラーハンドリングに関するトピックについて話す予定です。特に、エラーハンドリングの一環としてローカライズドエラーを用いて、どのようにエラーを返すことで特定のエラー処理を行うかを学びます。
本日はこれで終わります。お疲れ様でした。