Rust での unwrap, expect, panic, assert 周辺の話

unwrap, expect, panic!, assert! をいつ使うべきか、どういう意味で読んでいるか等。 雑にツイット集めただけなので誰か整理してくれ〜
3
前へ 1 ・・ 3 4 ・・ 7 次へ
らりお・ザ・.*🈗然㊌㋞㋰㋷㋓ @lo48576

型をな、作ろう……保証を型で表現しよう……

2020-12-22 17:18:21
Ryusei @mandel59

無理ならNoneを返すのって .unwrap() を使うより面倒くさいのかな

2020-12-22 17:19:29
らりお・ザ・.*🈗然㊌㋞㋰㋷㋓ @lo48576

そんで AdC の明日の枠用にスライス型を strong typedef するための解説記事を書いてるってワケ

2020-12-22 17:19:40
Ryusei @mandel59

None返すのだと意味わからんからResult型の方がいいと思うが

2020-12-22 17:20:27
らりお・ザ・.*🈗然㊌㋞㋰㋷㋓ @lo48576

@mandel59 仕様通りであれば発生しえないエラーを値として返すの、(用途にもよりますが)よろしくない気がしません? (internal inconsistency をエラーの一種として返すのかみたいな)

2020-12-22 17:21:01
らりお・ザ・.*🈗然㊌㋞㋰㋷㋓ @lo48576

仕様/実装バグを想定してエラー値として表現するの、それって全ての関数が潜在的に fn foo(in: In) -> Result<Out, ImplementationBug> みたいな表現になることを意味していて、これが合理的とはちょっと思えない

2020-12-22 17:21:49
らりお・ザ・.*🈗然㊌㋞㋰㋷㋓ @lo48576

仕様で起きえない None を返すために戻り値型を Option<T> にするというのはそういう世界観を受け入れることだと思っていて、そんなことをするよりは .expect("Should never happen because ...") すべきだと思う

2020-12-22 17:22:30
keno @keno_ss

エラーになったときのメッセージが入った .expect() を見すぎて感覚麻痺してたけど, 「(プログラム上満たされる constraints とかの) safety コメント書きながら unwrap() するなら expect() にしなよ」と言われてなるほどなーと思ったなど. なお, めんどくさいときは unwrap() を使ってます...

2020-12-22 17:26:53
Ryusei @mandel59

型システムがあるなら、仕様を型で表現して検査するのが一番いいはず

2020-12-22 17:28:33
Ryusei @mandel59

極力unsafeを使うべきでないのと同様に、極力panicも使うべきではない

2020-12-22 17:29:13
Ryusei @mandel59

unsafeと比べたらpanicは楽に見えるけど、型システムの穴なのはどっちも同じことでしょう

2020-12-22 17:30:42
keno @keno_ss

path.parent().expect("`path` is under `dir`") とかね.

2020-12-22 17:30:50
らりお・ザ・.*🈗然㊌㋞㋰㋷㋓ @lo48576

@mandel59 不整合の時点で一般にそれ以上の実行に意味を見出せないと思っていて (これは過去に書いたことが: blog.cardina1.red/2019/12/19/don…)、破棄するほかない実行パスで敢えてエラーを通知するというのは結局デバッグに使える情報を開発者に与える以上のものではないと思うので、であれば panic で良い気がします

2020-12-22 17:31:10
らりお・ザ・.*🈗然㊌㋞㋰㋷㋓ @lo48576

実装や仕様レベルのバグが型で表現されるべきかというの、私はバグは仕様の一部ではないためこれを型として表明するのは一般に無意味であると思っています。 もちろん例外はあって、たとえば外部プログラムを呼び出すがそっちに既知のバグがあるかもしれないとか。

2020-12-22 17:32:56
らりお・ザ・.*🈗然㊌㋞㋰㋷㋓ @lo48576

ただ、プログラム内部について言えば「既知のバグ」を仕様で表明するくらいなら修正すべきだという考えなので、必然的に「バグを実行時にうまく扱う必要があるのは、外部のコード由来の場合だけである」ということになる

2020-12-22 17:33:49
Ryusei @mandel59

@lo48576 自分がしているのは、手抜きのあるコードを書いたり、利用する場合に、安全にする話であって、不整合からの回復とは全然違う話なんですよね 「手抜き」は、単に実装されていない機能を利用したという話であって、それ自体ではなにも不整合を生んでいないという前提です。

2020-12-22 17:34:55
らりお・ザ・.*🈗然㊌㋞㋰㋷㋓ @lo48576

もうちょっとカジュアルな例を出すと、 fn add(x: i32, y: i32) -> i64 があったとして、「宇宙線でビット反転するかもしれない」みたいなのを fn add(x: i32, y: i32) -> Result<i64, HardwareError> と表現するかどうかは、それが仕様に含まれているかどうか次第だと思うんですよね

2020-12-22 17:34:58
らりお・ザ・.*🈗然㊌㋞㋰㋷㋓ @lo48576

ハードウェアの仕様として「特定の物理環境下で正しい結果が返らない場合があります」ということであればエラー型として扱えるべきだし、ソフトウェアの仕様として「宇宙線なんて考えません」で済まされる部分であればそれはインターフェースに露出すべきでない

2020-12-22 17:35:56
Ryusei @mandel59

望ましくない例としてResult<i64, HardwareError>を出したかもしれないけど、そもそも浮動小数点の加算だともとからNaNが仕様に含まれていますよね twitter.com/lo48576/status…

2020-12-22 17:38:43
らりお・ザ・.*🈗然㊌㋞㋰㋷㋓ @lo48576

たとえば「ノイズ由来と思しきビット反転が検出されたので、不整合があったらリトライします!」みたいな実装を前提にするなら、もちろんそういう「不整合」もエラーとして返却されるべきなんだけど、それも結局「不整合であるかどうか」というよりは「仕様の一部であるかどうか」が判断基準

2020-12-22 17:39:48
Ryusei @mandel59

気持ち=仕様とすれば、「気持ちを厳密に表明したい」「表明した気持ちは適切に処理されてほしい」という問題があるのなら、それに対する方法として自分がまっとうに感じるのは、それを型で表現することだと思います。

2020-12-22 17:43:23
Ryusei @mandel59

感じている気持ちは全部仕様とされるべきで、仕様の外のお気持ち表明、型の外のお気持ち表明は望ましくない。

2020-12-22 17:43:43
らりお・ザ・.*🈗然㊌㋞㋰㋷㋓ @lo48576

はい。 f32 / f64 で NaN がある一方で i32 / i64 にそれがない (ゼロ除算がクラッシュになる) というのも、結局「ゼロで割る場合の数値表現を仕様に含めない」という定めがあるからこそで、そういう前提の有無次第で「駄目なケースを型に露出させないことの正当性」も違うのではないかなと twitter.com/mandel59/statu…

2020-12-22 17:44:45
Ryusei @mandel59

宇宙線の話は型システムで保証できない範囲なので、それをするとややこしくなるが……

2020-12-22 17:45:51
前へ 1 ・・ 3 4 ・・ 7 次へ