エラー処理の方法として
- 単純な戻り値
- タプル
- 例外を投げる
- maybe/option/either
といったものがある。言語によって使える方法が違うが、これらは使い分けるべきものなのか?それとも 4 または 2 にすべて置き換えるべきものなのか?
少なくとも 1 がよろしくない、という分かりやすい例が下記にある。
この問題を タプルや option だとどう解決するか?
エラー処理の地学史、もしくはあなたがMaybeモナドを使うべき理由。 | 月と燃素と、ひと匙の砂糖
によれば、 hakell だとモナドを用いて
- func = do
- ok <- mayFail arg
- ok2 <- mayFail2 ok arg2
- ok3 <- mayFail3 ok2 arg3
- return (Just ok3)
こんな風に書けるらしいので、これを応用すればかけそう。
ちなみに、類似の問題に対して Scala だと for-yeild を使うのがよさそう。
for式のforeach/flatMap(map)展開について - Qiita
val a = Some(1) val b = Some("abc") val c = Some(0.5D) for { x <- a y <- b z <- c } { // a, b, cすべてに値が存在する場合のみ実行される println(s"$x, $y, $z") }
Haskellの maybe, Scala の for-yield 、Rust だとどう書くのがよい?
あ、上記のファイルの close は RAII の文脈で考えるべきかも。
... 調べた。
Rust の RAII は、Drop trait によって実現されているらしい。
The
Drop
trait only has one method:drop
, which is called automatically when an object goes out of scope. The main use of theDrop
trait is to free the resources that the implementor instance owns.
Box
,Vec
,String
,File
, andProcess
are some examples of types that implement theDrop
trait to free resources.
ということで、ファイルもスコープが外れると解放されるみたい。
ファイルを扱うクラスのコンストラクタでファイルを開き、ファイルディスクリプタを取得する。デストラクタでファイルを閉じ、ファイルディスクリプタを解放する。こうすることにより、オブジェクトのスコープを外れた時に確実にファイルは閉じられ、ディスクリプタは解放される。資源の解放に関する問題は、これで解決。
個々での問題は、ファイルのオープンに失敗した場合のエラー処理方法。
上記の例だと、3つのファイルを開いたとき、全部成功した場合の処理とどれか一つでも失敗した場合の処理を、どれだけ簡潔に分離して書けるか?ということ。