Programmingシステム開発者

Rustでのエラー処理について説明してください。panic!、Result、Optionの違いは何ですか?なぜRustでは例外が使用されないのですか?

Hintsage AIアシスタントで面接を突破

回答

RustにはJavaやC++のような一般的な例外は存在せず、代わりにエラー返却のためにタイプラッパーResultOptionが使用されます。

  • Result<T, E> — 値(Ok(T))またはエラー(Err(E))のいずれかを保持します。通常、正常に実行されない可能性のある操作(例えば、ファイルの入出力など)に使用されます。

  • Option<T> — オプショナルな値のために使用されます:Some(T)またはNoneで、エラーに関する情報はありません。例:

fn divide(x: f64, y: f64) -> Option<f64> { if y == 0.0 { None } else { Some(x / y) } }
  • panic! — プログラムの異常終了を引き起こします。「致命的なエラー」または「アサート」の形式です。ユーザーエラーの処理には使用せず、不変条件が破られた場合にのみ使用すべきです。

Rustにはtry/catchスタイルの例外が存在しないため、エラーの透過的で管理可能な流れを確保し、例外を維持するためにガベージコレクタやアンワインドエンジンを必要としません。

トリック質問

なぜpanic!を通常のエラー処理に使用できないのか?

回答:panic!は実行フローを終了させ、回復の機会を与えず、アンワインド/中止を引き起こします。一方、エラーがResultを介して返される場合、呼び出し側で処理することができます。例:

fn foo() -> Result<(), String> { Err("何かがうまくいかなかった".to_string()) } // 代わりに fn foo() { panic!("何かがうまくいかなかった"); }

このトピックに関する無知から生じる実際のエラーの例


物語

画像処理のマイクロサービスでは、開発者がすべての異常な状況の処理にpanic!を使用していました。これにより、エラーが発生するたびにサービスが異常終了し、クライアントにエラーの詳細を含む適切なHTTPレスポンスを返すことができませんでした。


物語

あるCLIツールでは、すべての入出力にunwrap()が使用され、可能なエラーの処理がされていませんでした。その結果、ファイルシステムのエラーが発生すると、プログラムは何のメッセージや診断もなく単に終了しました。


物語

分析サービスでは、わずかなエラーのためにOptionを使用しようとした結果、実際のエラー情報が失われ、デバッグが困難になりました。エラーの列挙体を持つResultに移行した後、バグを見つけて修正するのが容易になりました。