エラーハンドリング
エラーハンドリングは通常Error型に対するパターンマッチで行います。なるほど。
ただ、そのためにはBox<Error>のようにトレイトで隠蔽してしまうとハンドリング出来なくなるので
io::Errorなど具体的な型を使う必要がありす。
ただ、今回はProtobufErrorがio::Errorから変換出来るので具体的に扱えそうですね。
サンプルコードくらいでわざわざカッチり管理するのが面倒な時は`()`や`String`が`Error`を実装しているのでそれでどうにかするというのも手です。
因みにpanicからのrecoverはかなりの特殊用途向けなので基本的に使ってはいけません。
ブログでの疑問点についてコメント #1
今回の場合、事前にファイルの存在チェックを行わずにError型のパターンマッチで判定するにはこんな感じだろうか。
let path = Path::new(file_path); match File::open(&path) { Ok(file) => { let mut br = BufReader::new(file); let mut cis = CodedInputStream::from_buffered_reader(&mut br); address.merge_from(&mut cis)?; }, Err(e) => match e.kind() { io::ErrorKind::NotFound => (), _ => return Err(ProtobufError::IoError(e)), } }
また、
map_err(ProtobufError::IoError)
を呼ぶようにしている箇所はio::Error -> ProtobufErrorに変換するため各所にこのような行があります。との事だったが、rust-protobufリポジトリの方にPRが出ているようだ。
あまり ProtobufErrorの実装が良くない(本来ならFrom<io::Error>を実装すべき)のでこうなってます。
ブログでの疑問点についてコメント #1
String -> &strの明示的な変換
AsRef::as_refはメソッドとして(第一引数がselfとして)定義されているのでいくつか変換方法があるそうだが、今回は
String::as_ref(&args[1])よりもargs[1].as_ref()が好ましいというか正しい書き方です。
(以下略)
ブログでの疑問点についてコメント #1
args[1].as_ref()
に変更してみた。File::openで作ったファイルに書き込んでもエラーにならない?
ここからの一連のコメントとRustといえどリソースの解放は注意に詳しいが、BufWriter
のDrop
のタイミングで発生したエラーが無視されてこのような現象になったようだ。そもそも
CodeOutputStream
がバッファリングしているためBufWriter
を使う必要が無かったのでFile::create(&path)
で生成したstd::fs::File
をCodeOutputStream
に渡すようにしてみた。κeenさん、ありがとうございました。