競え
※前スレ
C++ vs Rust
https://mevius.5ch.net/test/read.cgi/tech/1619219089/
探検
C vs C++ vs Rust Part.2
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
2021/12/15(水) 12:35:50.91ID:biBE4xC0542デフォルトの名無しさん
2022/01/10(月) 02:26:23.03ID:yjEJqFVX543デフォルトの名無しさん
2022/01/10(月) 02:32:35.04ID:p+yOPw5a >>541
論理的に返答できる相手がどうかも論理的に考慮してくださいよ
論理的に返答できる相手がどうかも論理的に考慮してくださいよ
544デフォルトの名無しさん
2022/01/10(月) 03:15:13.62ID:B939XhoW 例外は危険なりよ。
545デフォルトの名無しさん
2022/01/10(月) 08:11:22.08ID:G9ZH73mK 有限回のイテレーションしか回せないことが分かっているのに無限ループで書くのはプログラムの論理的な誤りじゃないんだ?
メモリだのファイルディスクリプタだのPIDだのの枯渇、いわゆる通常の「リソース不足」と違って、事前に発生が完全に予見できるのに?
メモリだのファイルディスクリプタだのPIDだのの枯渇、いわゆる通常の「リソース不足」と違って、事前に発生が完全に予見できるのに?
546デフォルトの名無しさん
2022/01/10(月) 08:38:15.28ID:yjEJqFVX 一般的に対策としてはもっと大きな整数が扱える型を用いることになり行き着く先はBigInt
例えば以下のフィボナッチ数列を表示するプログラム
論理的な誤りがあると主張するならば具体的にどこをどう直しますか?
use num_bigint::BigInt;
fn main() {
let mut m: BigInt = 1.into();
let mut n: BigInt = 1.into();
loop {
println!("{}", m);
let next = m + n.clone();
m = n;
n = next;
}
}
例えば以下のフィボナッチ数列を表示するプログラム
論理的な誤りがあると主張するならば具体的にどこをどう直しますか?
use num_bigint::BigInt;
fn main() {
let mut m: BigInt = 1.into();
let mut n: BigInt = 1.into();
loop {
println!("{}", m);
let next = m + n.clone();
m = n;
n = next;
}
}
547デフォルトの名無しさん
2022/01/10(月) 08:43:23.03ID:gmQTKrMe548デフォルトの名無しさん
2022/01/10(月) 08:50:28.54ID:G9ZH73mK >>546
しれっとBigIntに直したそのプログラムには論理的な誤りがあると主張しません
>>538のi32版は論理的な誤りがあり、+の代わりにchecked_addを使って以下のように修正できます
fn main() {
let mut m: i32 = 1;
let mut n: i32 = 1;
loop {
println!("{}", m);
if let Some(next) = m.checked_add(n) {
m = n;
n = next;
} else {
break;
}
}
}
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=17058fd1c2a1c69f111ac09a94681ee6
しれっとBigIntに直したそのプログラムには論理的な誤りがあると主張しません
>>538のi32版は論理的な誤りがあり、+の代わりにchecked_addを使って以下のように修正できます
fn main() {
let mut m: i32 = 1;
let mut n: i32 = 1;
loop {
println!("{}", m);
if let Some(next) = m.checked_add(n) {
m = n;
n = next;
} else {
break;
}
}
}
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=17058fd1c2a1c69f111ac09a94681ee6
549デフォルトの名無しさん
2022/01/10(月) 08:56:07.29ID:pS98ddBp550デフォルトの名無しさん
2022/01/10(月) 08:57:32.63ID:pS98ddBp551デフォルトの名無しさん
2022/01/10(月) 09:03:32.42ID:yjEJqFVX552デフォルトの名無しさん
2022/01/10(月) 09:03:49.79ID:cQg1KnlR >>549
> 範囲を規定できる用途ばかりではないだろう
規定できる用途の方がはるかに多い
て言うかまともなプログラムなら規定してないなんてことはまずない
テストできないし
> そのケースは出来る限り多くのフィボナッチ数を出力したいのだから範囲を規定することがナンセンス
そんなケース滅多にないだろw
> 範囲を規定できる用途ばかりではないだろう
規定できる用途の方がはるかに多い
て言うかまともなプログラムなら規定してないなんてことはまずない
テストできないし
> そのケースは出来る限り多くのフィボナッチ数を出力したいのだから範囲を規定することがナンセンス
そんなケース滅多にないだろw
553デフォルトの名無しさん
2022/01/10(月) 09:07:37.24ID:G9ZH73mK >>551
「チェック付き演算に置き換えて回避可能」は「本質的にリカバリできない」に含まれるのか?
ていうかそもそもその区分は何のために存在するんだ?
Rustが例外を採用しない理由として言語開発者たちがそのように主張しているのか?
それとも君の感想?
「チェック付き演算に置き換えて回避可能」は「本質的にリカバリできない」に含まれるのか?
ていうかそもそもその区分は何のために存在するんだ?
Rustが例外を採用しない理由として言語開発者たちがそのように主張しているのか?
それとも君の感想?
554デフォルトの名無しさん
2022/01/10(月) 09:20:25.60ID:yjEJqFVX >>553
前者はpanicを回避可能
それでも計算続行不可能という点では後者の本質的にリカバリできないに該当なのかな
だからそれらは両立していると思うのだがどうだろうか?
あと「例外を採用しない理由」をなぜここで突然言及するのか疑問だが
もし以下の話について言っているのならば
>>532
>> Rustがtry-catchの例外機構を持たない理由は非常に単純で
>> (A) 本質的にリカバリできることは通常のエラー処理だけで十分に対処可
>> (B) 本質的にリカバリできないことはpanic
チェック付き演算を使用した場合は前者になるし
使用せずにオーバーフローすれば後者になるのだから
そこに何か明白でない論点はないと思うのだがどうだろうか?
前者はpanicを回避可能
それでも計算続行不可能という点では後者の本質的にリカバリできないに該当なのかな
だからそれらは両立していると思うのだがどうだろうか?
あと「例外を採用しない理由」をなぜここで突然言及するのか疑問だが
もし以下の話について言っているのならば
>>532
>> Rustがtry-catchの例外機構を持たない理由は非常に単純で
>> (A) 本質的にリカバリできることは通常のエラー処理だけで十分に対処可
>> (B) 本質的にリカバリできないことはpanic
チェック付き演算を使用した場合は前者になるし
使用せずにオーバーフローすれば後者になるのだから
そこに何か明白でない論点はないと思うのだがどうだろうか?
555デフォルトの名無しさん
2022/01/10(月) 09:31:36.48ID:aaWRldUf >>546
それリソース不足にはなるけどオーバーフローにはならないよね?
それリソース不足にはなるけどオーバーフローにはならないよね?
556デフォルトの名無しさん
2022/01/10(月) 09:44:54.40ID:pS98ddBp557デフォルトの名無しさん
2022/01/10(月) 11:51:44.97ID:mx4R5SfM 今日はNGしやすくて助かる
いつもこの調子で頼むよ
いつもこの調子で頼むよ
558デフォルトの名無しさん
2022/01/10(月) 12:01:05.13ID:m6EPjr42 >>553
リカバリできないかどうかは状況に応じて開発者が主観的に判断するものなので
「本質的にリカバリできない」かどうかを考えるのは無意味
エラーハンドリングの基本
もちろんRustの言語開発者も同じ考え方
https://doc.rust-lang.org/book/ch09-03-to-panic-or-not-to-panic.html
リカバリできないかどうかは状況に応じて開発者が主観的に判断するものなので
「本質的にリカバリできない」かどうかを考えるのは無意味
エラーハンドリングの基本
もちろんRustの言語開発者も同じ考え方
https://doc.rust-lang.org/book/ch09-03-to-panic-or-not-to-panic.html
559デフォルトの名無しさん
2022/01/10(月) 12:12:45.84ID:pS98ddBp Rustはそこに書いてあるようにエラーをResultで返すかpanicかの2択で済むもんな
560デフォルトの名無しさん
2022/01/10(月) 13:03:25.90ID:EipmFK9a561デフォルトの名無しさん
2022/01/10(月) 13:56:51.54ID:uivNzQl2 数値型のオーバーフローをリソース不足と言って共感得るのは無理だろうな
プログラムにおける上限下限は暗黙的または経験則的に考慮して設計実装されるし、まともなユニットテスト書けば当然検出されるバグ
仮にオープンソースとして世に出すなら、マニュアルやバグレポートに対してどう対処するのか興味ある
プログラムにおける上限下限は暗黙的または経験則的に考慮して設計実装されるし、まともなユニットテスト書けば当然検出されるバグ
仮にオープンソースとして世に出すなら、マニュアルやバグレポートに対してどう対処するのか興味ある
562デフォルトの名無しさん
2022/01/10(月) 14:09:36.74ID:NhSa0Exb 曖昧な例外を廃して、とかいっても結局そういう「経験的」とかいう曖昧なレベルでしかなされてないってことよな
563デフォルトの名無しさん
2022/01/10(月) 14:16:44.51ID:pnnjNIgm 本人の理解が曖昧なだけだから
564デフォルトの名無しさん
2022/01/11(火) 15:22:08.76ID:2061HgWk 結局try catch例外処理なんて最初から不要なものだったんだな
だから最近の言語RustやGoにはそのような無駄なものがないわけだ
だから最近の言語RustやGoにはそのような無駄なものがないわけだ
565デフォルトの名無しさん
2022/01/11(火) 15:51:54.57ID:t1MM9BO+ Rustが例外機構を無くとも同等のことを快適に記述できる要因は二つ
HaskellのEitherモナドを値付きenumとして表現したResult<T,E>を関数の戻り型としたこと
そしてResultがErrの時に?オペレーターにより見えない即時returnをするショートカットを用意したこと
HaskellのEitherモナドを値付きenumとして表現したResult<T,E>を関数の戻り型としたこと
そしてResultがErrの時に?オペレーターにより見えない即時returnをするショートカットを用意したこと
566デフォルトの名無しさん
2022/01/11(火) 16:40:23.19ID:wv+/KAmB 気持ち悪い自演はもうやめてーー
567デフォルトの名無しさん
2022/01/11(火) 21:12:28.05ID:LUMp2LI9 検査例外と一緒なんだけどね
568デフォルトの名無しさん
2022/01/11(火) 21:26:17.78ID:xKqG3MQU そういえば例外の信奉者ほどJavaの検査例外を糞味噌に言うけど、例外機構の型検査をきっちりやろうとしたら
ああいう方法しかないわけだよね。
ああいう方法しかないわけだよね。
569デフォルトの名無しさん
2022/01/11(火) 23:24:53.53ID:Ijlv3HIe フロントエンドやサーバーサイドは間欠故障まではあっても、大抵リトライとタイムアウトで救える
バックエンドの耐障害性の設計がまともなら、だけど
そりゃエラーチェックなんて馬鹿らしくなるわな
バックエンドの耐障害性の設計がまともなら、だけど
そりゃエラーチェックなんて馬鹿らしくなるわな
570デフォルトの名無しさん
2022/01/11(火) 23:38:16.29ID:Htfqiioy 大半のアプリケーションでは個別にハンドリングせず
集約エラーハンドラに任せたいとエラーのほうが圧倒的多数だから
呼び出し階層全てにどの例外が発生しうるかを書いていかないといけない検査例外が嫌われるのは自然なこと
Javaの場合は例外クラスの階層の問題とかその他の要素も相まって糞味噌扱い
集約エラーハンドラに任せたいとエラーのほうが圧倒的多数だから
呼び出し階層全てにどの例外が発生しうるかを書いていかないといけない検査例外が嫌われるのは自然なこと
Javaの場合は例外クラスの階層の問題とかその他の要素も相まって糞味噌扱い
571デフォルトの名無しさん
2022/01/11(火) 23:39:37.20ID:2061HgWk なるほど
こういう理解であってますか?
「Javaの検査例外」と「RustのResult/Optionエラー処理」を比較すると
(共通点)
以下をコンパイル時点で強制することで安全性を保証
「誰かがエラー時の捕獲と処理(Javaではcatch、Rustではmatch等)を必ずしていること」
(相違点)
Javaでは例外と同じtry-catchを利用 (そのため入れ子で例外が握り潰されたりややこしい)
Rustでは例外はなく通常の関数呼び出しと値返し処理となり、
関数の返す型がResultまたはOptionのenum型、
多段呼び出しの場合に途中で「?」使用によりエラー時にスルー可、
自分もしくは上位の誰かがResultまたはOptionのenum値をチェックしてエラー処理
Rustではエラー時にエラー表示して終了で良い場合は以下の楽にサボる方法もサポート
最上位のmain()がResult/Optionを返すことで自動的にエラー時に表示終了
ResultまたはOptionをunwrap()等してエラー時に即時panic終了
このpanic終了はスレッド単位やタスク単位も可能なのでサボりサーバー等も実装可
こういう理解であってますか?
「Javaの検査例外」と「RustのResult/Optionエラー処理」を比較すると
(共通点)
以下をコンパイル時点で強制することで安全性を保証
「誰かがエラー時の捕獲と処理(Javaではcatch、Rustではmatch等)を必ずしていること」
(相違点)
Javaでは例外と同じtry-catchを利用 (そのため入れ子で例外が握り潰されたりややこしい)
Rustでは例外はなく通常の関数呼び出しと値返し処理となり、
関数の返す型がResultまたはOptionのenum型、
多段呼び出しの場合に途中で「?」使用によりエラー時にスルー可、
自分もしくは上位の誰かがResultまたはOptionのenum値をチェックしてエラー処理
Rustではエラー時にエラー表示して終了で良い場合は以下の楽にサボる方法もサポート
最上位のmain()がResult/Optionを返すことで自動的にエラー時に表示終了
ResultまたはOptionをunwrap()等してエラー時に即時panic終了
このpanic終了はスレッド単位やタスク単位も可能なのでサボりサーバー等も実装可
572デフォルトの名無しさん
2022/01/11(火) 23:52:36.57ID:Htfqiioy Rustも呼び出し階層全てでどのエラーが発生しうるか型で管理しないといけないからJavaの検査例外と同じ面倒臭さがある
面倒臭いからといって全部Result<T, Box<dyn Error>>にしちゃうと何のエラーが発生するのか分からなくなってしまう
面倒臭さと堅牢さのトレードオフ
面倒臭いからといって全部Result<T, Box<dyn Error>>にしちゃうと何のエラーが発生するのか分からなくなってしまう
面倒臭さと堅牢さのトレードオフ
573デフォルトの名無しさん
2022/01/11(火) 23:58:57.17ID:2061HgWk574デフォルトの名無しさん
2022/01/12(水) 01:37:24.08ID:nBmB5mPZ 戻り値を返さないコンストラクタやデストラクタ内でエラーが発生したら、例外
以外に通知する方法があるなら教えてほしい。
例外ハンドラを書かないって、エラー処理を一切しない、例えばディスクが一杯で
書き込めないとか、何かあると問答無用で落ちるプログラムってことだぞ。
以外に通知する方法があるなら教えてほしい。
例外ハンドラを書かないって、エラー処理を一切しない、例えばディスクが一杯で
書き込めないとか、何かあると問答無用で落ちるプログラムってことだぞ。
575デフォルトの名無しさん
2022/01/12(水) 01:42:57.07ID:zk3KtN+K 例外 (panic) 以外ないね
エラーが発生しうる処理はデストラクタが呼ばれる前にやるべきかな
RustでもBufWriterなんかがスコープアウトでdrop呼び出される前に明示的にflush必要だったりする (drop内のcloseで発生するエラーは無視される)
エラーが発生しうる処理はデストラクタが呼ばれる前にやるべきかな
RustでもBufWriterなんかがスコープアウトでdrop呼び出される前に明示的にflush必要だったりする (drop内のcloseで発生するエラーは無視される)
576デフォルトの名無しさん
2022/01/12(水) 02:19:37.87ID:Fd1MyF0L577デフォルトの名無しさん
2022/01/12(水) 11:53:11.60ID:EMNsA0zN >>574
コンストラクタやデストラクタ内ではエラーが発生しないように作れって習わなかった?
それでも避けようのないエラーなら落としたほうがいい
プログラム全体を落としたくなければスレッドやプロセスを落とす
コンストラクタやデストラクタ内ではエラーが発生しないように作れって習わなかった?
それでも避けようのないエラーなら落としたほうがいい
プログラム全体を落としたくなければスレッドやプロセスを落とす
578デフォルトの名無しさん
2022/01/12(水) 12:24:49.11ID:tJ2PyYKm C++で例外安全をちゃんとやるの難しそう
579デフォルトの名無しさん
2022/01/12(水) 12:30:04.82ID:ii0KI3af >>577
デストラクタでエラーはまずいけどコンストラクタで避ける理由は無かろう。
[迷信] コンストラクタから例外を送出してはならない
https://www.kijineko.co.jp/%E8%BF%B7%E4%BF%A1-%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF%E3%81%8B%E3%82%89%E4%BE%8B%E5%A4%96%E3%82%92%E9%80%81%E5%87%BA%E3%81%97%E3%81%A6%E3%81%AF%E3%81%AA%E3%82%89/
デストラクタでエラーはまずいけどコンストラクタで避ける理由は無かろう。
[迷信] コンストラクタから例外を送出してはならない
https://www.kijineko.co.jp/%E8%BF%B7%E4%BF%A1-%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88%E3%83%A9%E3%82%AF%E3%82%BF%E3%81%8B%E3%82%89%E4%BE%8B%E5%A4%96%E3%82%92%E9%80%81%E5%87%BA%E3%81%97%E3%81%A6%E3%81%AF%E3%81%AA%E3%82%89/
580デフォルトの名無しさん
2022/01/12(水) 12:31:30.95ID:ii0KI3af >>578 Rustなんかだと何か簡単になるの?
581デフォルトの名無しさん
2022/01/12(水) 12:54:54.70ID:zk3KtN+K unsafeのpanic-safeはそれなりに気を遣わないといけないよね
safeだと特に何も考えなくても良い?
safeだと特に何も考えなくても良い?
582デフォルトの名無しさん
2022/01/12(水) 14:16:26.71ID:gLPtO7rz C++は何種類もコンストラクタがあって大変だが
Rustはコンストラクタが無いため問題は発生しない
Rustにも自動で呼ばれるデストラクタはあるが
その前に捕獲すべきエラーが発生しうるものを自分で処理しておくので無問題
Rustはコンストラクタが無いため問題は発生しない
Rustにも自動で呼ばれるデストラクタはあるが
その前に捕獲すべきエラーが発生しうるものを自分で処理しておくので無問題
583デフォルトの名無しさん
2022/01/12(水) 20:35:54.02ID:xJEGl+xo 俺はコンストラクタで例外投げないし投げさせないな
コマンドのような短命プロセスで雑な実装で良いとか、必然性があるなら別だけど
コマンドのような短命プロセスで雑な実装で良いとか、必然性があるなら別だけど
584デフォルトの名無しさん
2022/01/12(水) 21:30:33.58ID:zk3KtN+K コンストラクタと言ってるからc++だと思うけど事前条件を満たさないでコンストラクタが呼び出されたらどうするの?
585デフォルトの名無しさん
2022/01/12(水) 21:36:50.23ID:MHAI7amN 南無三!と叫びながらreturn
586デフォルトの名無しさん
2022/01/12(水) 22:39:14.21ID:CbaowxsH587デフォルトの名無しさん
2022/01/12(水) 22:42:53.89ID:5pTy1wN9 いやわかるやろ
長期間安定して走らないといけないプログラムとそうでないのとはあるやろ
長期間安定して走らないといけないプログラムとそうでないのとはあるやろ
588デフォルトの名無しさん
2022/01/12(水) 23:16:19.38ID:DMKGOQqO >>584
ファクトリメソッド経由でしかコンストラクタは呼び出せないようにするんだよ
ファクトリメソッド経由でしかコンストラクタは呼び出せないようにするんだよ
589デフォルトの名無しさん
2022/01/12(水) 23:43:13.07ID:DMKGOQqO コンストラクタでエラーが発生しないようにするのはリークの問題じゃなくて使いやすさの問題
new Hoge()を呼べるなら個別にハンドリングが必要なエラーは発生しないと分かるのが重要
デストラクタと違ってコーディング規約的なもの
new Hoge()を呼べるなら個別にハンドリングが必要なエラーは発生しないと分かるのが重要
デストラクタと違ってコーディング規約的なもの
590デフォルトの名無しさん
2022/01/13(木) 00:32:37.82ID:RultHF/h >>589
コーディング規約(w
コンストラクタ内で、動的配列のクラスやテンプレートを使ってると、例外が発生する
可能性は常にある。 他の言語は知らんが、C++の場合、コンストラクタ内で例外が
発生すると、デストラクタは呼ばれない。
コーディング規約(w
コンストラクタ内で、動的配列のクラスやテンプレートを使ってると、例外が発生する
可能性は常にある。 他の言語は知らんが、C++の場合、コンストラクタ内で例外が
発生すると、デストラクタは呼ばれない。
591デフォルトの名無しさん
2022/01/13(木) 00:41:21.53ID:RultHF/h 例えば、ファイルハンドルをラップしたファイルクラスがあったとして、引数なしの
デフォルトコンストラクタと、引数でオープン済のファイルハンドルを渡すコンスト
ラクタを定義したとして、後者のコンストラクタが無効なファイルハンドルを引数
として呼ばれたら、例外をスローするように実装するだろ?
後者のコンストラクタは、dup()で複製したファイルハンドル等を扱う際に必要。
デフォルトコンストラクタと、引数でオープン済のファイルハンドルを渡すコンスト
ラクタを定義したとして、後者のコンストラクタが無効なファイルハンドルを引数
として呼ばれたら、例外をスローするように実装するだろ?
後者のコンストラクタは、dup()で複製したファイルハンドル等を扱う際に必要。
592デフォルトの名無しさん
2022/01/13(木) 01:53:08.91ID:hGSK4csp >>591
ファイルハンドルが無効な場合をエラーとして処理すべきならコンストラクタを直接使わせずファクトリー経由にする
panic相当の例外として処理すべきならコンストラクタ使って例外スローでかわまない
ファイルハンドルが無効な場合をエラーとして処理すべきならコンストラクタを直接使わせずファクトリー経由にする
panic相当の例外として処理すべきならコンストラクタ使って例外スローでかわまない
593デフォルトの名無しさん
2022/01/13(木) 05:45:30.92ID:aa54J19o >>587
それとコンストラクタで例外発生させないことは関係なくね?
それとコンストラクタで例外発生させないことは関係なくね?
594デフォルトの名無しさん
2022/01/13(木) 07:16:55.50ID:QuitFgmw コンストラクタも例外も存在しないRustでは問題自体が生じない
>>591のケースでもRustでは後者のビルダー関数がResultを返すだけで済む
>>591のケースでもRustでは後者のビルダー関数がResultを返すだけで済む
595デフォルトの名無しさん
2022/01/13(木) 08:12:03.99ID:RultHF/h Rustって、名前の通り錆付いてるようだな。 例外(Exception)がないって、要は
Panicって名前とtry〜catchと互換性のない俺仕様の記述を発明しただけじゃん。
ttps://news.ycombinator.com/item?id=11370841
ttps://www.reddit.com/r/rust/comments/bzaxf2/why_rust_doesnt_have_exception_handling/
ttp://joeduffyblog.com/2016/02/07/the-error-model/
返す型を限定するのは、C++でもコーディング規約で縛れば済むだけの話だし。
結局、Nullポインタ程度で騒いでいるのは、マニュアルフォーカスのカメラでピンボケ
するとか、マニュアルミッションの車でクラッチ繋ぐのミスると、エンストするって
言ってるのと変わらん気がするナァ。
Panicって名前とtry〜catchと互換性のない俺仕様の記述を発明しただけじゃん。
ttps://news.ycombinator.com/item?id=11370841
ttps://www.reddit.com/r/rust/comments/bzaxf2/why_rust_doesnt_have_exception_handling/
ttp://joeduffyblog.com/2016/02/07/the-error-model/
返す型を限定するのは、C++でもコーディング規約で縛れば済むだけの話だし。
結局、Nullポインタ程度で騒いでいるのは、マニュアルフォーカスのカメラでピンボケ
するとか、マニュアルミッションの車でクラッチ繋ぐのミスると、エンストするって
言ってるのと変わらん気がするナァ。
596デフォルトの名無しさん
2022/01/13(木) 08:32:43.99ID:pYL+3tES >>595
開発人数が増えると規約を守らせるコストが大きくなるからね
開発人数が増えると規約を守らせるコストが大きくなるからね
597デフォルトの名無しさん
2022/01/13(木) 08:53:54.36ID:QuitFgmw >>595
panicと例外は全く異なる
議論に立ち入りたいならばせめて最小限の理解をしよう
完成した通常のプログラムにおいてpanicが発生するのはメモリ不足の時のみ
次に、例外はそもそも必要ないことに気付こう
エラーが発生する可能性があるならばエラーを返せばよいだけだ
これでプログラミングにおいて困ることはない
try〜catchの例外機構はそもそも必要のないものだったのだ
panicと例外は全く異なる
議論に立ち入りたいならばせめて最小限の理解をしよう
完成した通常のプログラムにおいてpanicが発生するのはメモリ不足の時のみ
次に、例外はそもそも必要ないことに気付こう
エラーが発生する可能性があるならばエラーを返せばよいだけだ
これでプログラミングにおいて困ることはない
try〜catchの例外機構はそもそも必要のないものだったのだ
598デフォルトの名無しさん
2022/01/13(木) 12:20:53.94ID:VLvCS3li599デフォルトの名無しさん
2022/01/13(木) 12:34:07.73ID:k/BdCeDW600デフォルトの名無しさん
2022/01/13(木) 13:04:20.54ID:nB26Onrd その点も含めて、少なくとも >597 の「全く異なる」は嘘だね。
後段の「エラーが発生する可能性があるならばエラーを返せばよいだけだ」についても、
じゃぁ何で panic があるの?ってなるし、どういうわけか例外憎しで適当なこと言いたいだけみたい。
後段の「エラーが発生する可能性があるならばエラーを返せばよいだけだ」についても、
じゃぁ何で panic があるの?ってなるし、どういうわけか例外憎しで適当なこと言いたいだけみたい。
601デフォルトの名無しさん
2022/01/13(木) 13:23:05.77ID:k/BdCeDW rustのpanicとかエラーハンドリングの考え方はgolangの影響大きい気はする
Result型を使うか多値でエラーを返すかの違いはあるが、panicという名前と動作、戻り値との使い分けは同じ
Result型を使うか多値でエラーを返すかの違いはあるが、panicという名前と動作、戻り値との使い分けは同じ
602デフォルトの名無しさん
2022/01/13(木) 13:24:11.54ID:k/BdCeDW なので >>595 のrustは俺仕様を発明したという指摘も事実と異なると思う
603デフォルトの名無しさん
2022/01/13(木) 14:47:56.89ID:ToUR5G3E エラーモデルの理解が浅い人を寄ってたかって叩いたところで得るものはないぞ
604デフォルトの名無しさん
2022/01/13(木) 15:05:09.73ID:2BXAobev >>598
panicはバグ発生かメモリ不足でのみ起きる。
だから通常フローへの復帰はせずにabortとなる。
abort前に後処理をしたい時やデバッグ情報を出したい時のためにstd::panic::catch_unwindがある。
それらの処理のためにスタックが巻き戻る。
>>600
一方でtry catch例外処理はpanicとは完全に異なるものである。
単なるエラー処理でも使われて通常フローへの復帰をする。
そのためtry catchが言語の構文となっている言語も多い。
GoやRustにはこの例外処理はなくtry catchも無い。
プログラミングにおいて、エラー処理のためのtry catch例外処理は本来不要なものである。
エラーは関数の戻り値で返せばよい。
このように本来のやり方でエラーを返すのがGoやRustであり、これで実際に動いている。
つまり、単なるエラー処理のための例外機構は必要ないものであることがわかる。
panicはバグ発生かメモリ不足でのみ起きる。
だから通常フローへの復帰はせずにabortとなる。
abort前に後処理をしたい時やデバッグ情報を出したい時のためにstd::panic::catch_unwindがある。
それらの処理のためにスタックが巻き戻る。
>>600
一方でtry catch例外処理はpanicとは完全に異なるものである。
単なるエラー処理でも使われて通常フローへの復帰をする。
そのためtry catchが言語の構文となっている言語も多い。
GoやRustにはこの例外処理はなくtry catchも無い。
プログラミングにおいて、エラー処理のためのtry catch例外処理は本来不要なものである。
エラーは関数の戻り値で返せばよい。
このように本来のやり方でエラーを返すのがGoやRustであり、これで実際に動いている。
つまり、単なるエラー処理のための例外機構は必要ないものであることがわかる。
605デフォルトの名無しさん
2022/01/13(木) 15:34:59.47ID:oax73caB606デフォルトの名無しさん
2022/01/13(木) 15:50:06.61ID:E5YlFTVp >>604
> プログラミングにおいて、エラー処理のためのtry catch例外処理は本来不要なものである。
> エラーは関数の戻り値で返せばよい。
あらゆる関数/メソッド呼び出しのたびにエラーチェックをするのが煩雑だから、try-catchが生み出されたんだと思う。
例えば、データベースアクセスが発生する三つの関数を呼び出すとき、
try {
foo();
bar();
baz();
commit();
} catch () {
rollback();
}
みたいな。
続行不能なエラーが発生したが、本流に戻る必要があるときは便利。
> プログラミングにおいて、エラー処理のためのtry catch例外処理は本来不要なものである。
> エラーは関数の戻り値で返せばよい。
あらゆる関数/メソッド呼び出しのたびにエラーチェックをするのが煩雑だから、try-catchが生み出されたんだと思う。
例えば、データベースアクセスが発生する三つの関数を呼び出すとき、
try {
foo();
bar();
baz();
commit();
} catch () {
rollback();
}
みたいな。
続行不能なエラーが発生したが、本流に戻る必要があるときは便利。
607デフォルトの名無しさん
2022/01/13(木) 15:52:35.91ID:2BXAobev >>605
話がごっちゃになっているのはtry catchの例外処理。
Rustでpanicが起きるのはバグとメモリ不足であり、絶対に起きてはいけない状況。
だからpanicの標準動作はそのままabortとなっている。
一方でエラー処理は起き得ることだから関数の戻り値で返す。
一方でtry catchの例外処理は、それらをごっちゃにまとめて扱っている。
単なるエラー処理を、なぜ、try catchで扱ってしまうのか?
それは関数の仕様設計ミスである。
ちゃんとエラーを返せば、単なるエラー処理のための例外処理は不要となる。
話がごっちゃになっているのはtry catchの例外処理。
Rustでpanicが起きるのはバグとメモリ不足であり、絶対に起きてはいけない状況。
だからpanicの標準動作はそのままabortとなっている。
一方でエラー処理は起き得ることだから関数の戻り値で返す。
一方でtry catchの例外処理は、それらをごっちゃにまとめて扱っている。
単なるエラー処理を、なぜ、try catchで扱ってしまうのか?
それは関数の仕様設計ミスである。
ちゃんとエラーを返せば、単なるエラー処理のための例外処理は不要となる。
608デフォルトの名無しさん
2022/01/13(木) 15:56:44.41ID:wvcpI8iw Rust擁護するあまり無理筋の論理展開だな
プログラミングに必須じゃない機能は不要と言い出したらキリないのでは
プログラミングに必須じゃない機能は不要と言い出したらキリないのでは
609デフォルトの名無しさん
2022/01/13(木) 15:59:01.01ID:k/BdCeDW610デフォルトの名無しさん
2022/01/13(木) 16:20:05.76ID:2BXAobev >>606
Rustなら色々やり方あろうけど、わかりやすい例にするとこうなる。
fn main() {
match sub() {
Ok(result) => { commit(); println!("OK: {}", result); },
Err(err) => { rollback(); println!("ERROR: {}", err); },
}
}
sub() -> Result<DataType, Error> {
let a = foo()?;
let b = bar()?;
baz(a, b)
}
foo(), bar(), baz()各々はResultでエラー値も同時に返しているが、エラーチェックはまとめて出来る。
ResultはOkとErrの2つを取るenumであり、matchは強力なswitch相当と思っていただければいい。
try catchといった例外処理がなくてもプログラミングで困ることはない。
Rustなら色々やり方あろうけど、わかりやすい例にするとこうなる。
fn main() {
match sub() {
Ok(result) => { commit(); println!("OK: {}", result); },
Err(err) => { rollback(); println!("ERROR: {}", err); },
}
}
sub() -> Result<DataType, Error> {
let a = foo()?;
let b = bar()?;
baz(a, b)
}
foo(), bar(), baz()各々はResultでエラー値も同時に返しているが、エラーチェックはまとめて出来る。
ResultはOkとErrの2つを取るenumであり、matchは強力なswitch相当と思っていただければいい。
try catchといった例外処理がなくてもプログラミングで困ることはない。
611デフォルトの名無しさん
2022/01/13(木) 16:27:12.94ID:E5YlFTVp >>609
> べき論の話で言ったらC++もエラー処理には戻り値を使うべき
>>606 のコードをこんな感じで書くの?
int process()
{
if (foo() != 0)
return -1;
if (bar() != 0)
return -1;
if (baz() != 0)
return -1;
return 0;
}
int hoge()
{
if (begin() != 0)
return -1;
int ret = porcess();
if (ret == 0) {
if (commit() = 0)
return 0;
}
(void)rollback();
return -1;
}
> べき論の話で言ったらC++もエラー処理には戻り値を使うべき
>>606 のコードをこんな感じで書くの?
int process()
{
if (foo() != 0)
return -1;
if (bar() != 0)
return -1;
if (baz() != 0)
return -1;
return 0;
}
int hoge()
{
if (begin() != 0)
return -1;
int ret = porcess();
if (ret == 0) {
if (commit() = 0)
return 0;
}
(void)rollback();
return -1;
}
612デフォルトの名無しさん
2022/01/13(木) 16:28:29.38ID:E5YlFTVp613デフォルトの名無しさん
2022/01/13(木) 16:36:22.32ID:E5YlFTVp あ、ひょっとして「?;」ってエラーが発生したらそこでsub()を抜けるってこと?
まあ、だとしても、C++でもエラーチェックベースで実装しろということにはならないけどね
まあ、だとしても、C++でもエラーチェックベースで実装しろということにはならないけどね
614デフォルトの名無しさん
2022/01/13(木) 16:42:23.86ID:E5YlFTVp 大抵の言語では、例外が発生したらスタックトレースが取れたり、例外オブジェクトそのものにエラー発生場所・エラーコード・エラーメッセージなんかが入ってたりするから、使わない手はないと思うよ
615デフォルトの名無しさん
2022/01/13(木) 16:57:19.52ID:2BXAobev >>611
その場合でも、Rustならば戻り値をResultにしてこのように見やすくプログラミングしやすい。
fn process() -> Result<(), Error> {
foo()?;
bar()?;
baz()
}
fn hoge() -> Result<(), Error> {
begin()?;
match process() {
Ok(()) => {
commit()?;
Ok(())
},
Err(err) => {
rollback();
Err(err)
},
}
}
>>613
その通り
?オペレータは、ResultがErr(err)の時にreturn Err(err);する。
正確には便利に変換してくれるreturn Err(From::from(err));だが本筋でないので略。
その場合でも、Rustならば戻り値をResultにしてこのように見やすくプログラミングしやすい。
fn process() -> Result<(), Error> {
foo()?;
bar()?;
baz()
}
fn hoge() -> Result<(), Error> {
begin()?;
match process() {
Ok(()) => {
commit()?;
Ok(())
},
Err(err) => {
rollback();
Err(err)
},
}
}
>>613
その通り
?オペレータは、ResultがErr(err)の時にreturn Err(err);する。
正確には便利に変換してくれるreturn Err(From::from(err));だが本筋でないので略。
616デフォルトの名無しさん
2022/01/13(木) 17:01:12.46ID:E5YlFTVp >>615
> ?オペレータは、ResultがErr(err)の時にreturn Err(err);する。
なるほど、勉強になった
ただ、前述したとおり、書き捨てのプログラムでない限りエラーが発生したときには詳細なエラーログを出力する必要もあるし、Rustの常識が多言語でもベストプラクティスとはならないと思うよ
> ?オペレータは、ResultがErr(err)の時にreturn Err(err);する。
なるほど、勉強になった
ただ、前述したとおり、書き捨てのプログラムでない限りエラーが発生したときには詳細なエラーログを出力する必要もあるし、Rustの常識が多言語でもベストプラクティスとはならないと思うよ
617デフォルトの名無しさん
2022/01/13(木) 17:09:11.61ID:k/BdCeDW618デフォルトの名無しさん
2022/01/13(木) 17:24:20.34ID:2BXAobev >>614
スタックトレースまで必要になるならば、それはエラーではなくプログラムのバグだろう。
その区別を付けたほうが好ましい。
そして、エラーではなくバグならば前述したようにpanicの対象なのでpanicさせることもできる。
>>616
Resultの正常値もエラー値も任意の情報を持たせられるので必要な時に必要な処理をすれば困ることはない。
>>617
そのGoogleのC++スタイルガイドに「C++の例外は使いません。」と明記されているのか。
これはGoogleが正しい。
もちろん、Googleが作ったGo言語に例外はない。
プログラミングにおいてtry catchの例外機構は不要である。
スタックトレースまで必要になるならば、それはエラーではなくプログラムのバグだろう。
その区別を付けたほうが好ましい。
そして、エラーではなくバグならば前述したようにpanicの対象なのでpanicさせることもできる。
>>616
Resultの正常値もエラー値も任意の情報を持たせられるので必要な時に必要な処理をすれば困ることはない。
>>617
そのGoogleのC++スタイルガイドに「C++の例外は使いません。」と明記されているのか。
これはGoogleが正しい。
もちろん、Googleが作ったGo言語に例外はない。
プログラミングにおいてtry catchの例外機構は不要である。
619デフォルトの名無しさん
2022/01/13(木) 17:55:38.36ID:QuitFgmw try/catchよりもRustの方法が良い点としては
let val = foo()?; とした時に
正常値valの時だけに専念できるだけでなく
foo()はエラーを返すこともあってその処理は上位に委譲していますよ!と
?オペレーターの存在で明瞭になる点
これは裏返せばtry/catch例外方式の致命的な欠点
どこで誰が例外を返すのかわからなかったり
多段呼び出しの途中の関数では例外が通過するのかどうか全てを追わないとわからなかったり
プログラミングにおいて例外は悪だと思う
グーグルはちゃんとわかっている
let val = foo()?; とした時に
正常値valの時だけに専念できるだけでなく
foo()はエラーを返すこともあってその処理は上位に委譲していますよ!と
?オペレーターの存在で明瞭になる点
これは裏返せばtry/catch例外方式の致命的な欠点
どこで誰が例外を返すのかわからなかったり
多段呼び出しの途中の関数では例外が通過するのかどうか全てを追わないとわからなかったり
プログラミングにおいて例外は悪だと思う
グーグルはちゃんとわかっている
620デフォルトの名無しさん
2022/01/13(木) 18:12:05.30ID:E5YlFTVp >>618
> スタックトレースまで必要になるならば、それはエラーではなくプログラムのバグだろう。
エラーが発生した場所がどこであるのかが例外オブジェクトに含まれているなら、スタックトレースが不要な場合もあるかもしれませんが、あればどういう呼び出しのときにエラーが発生したのかわかるので便利です
> その区別を付けたほうが好ましい。
大抵の場合は例外の種別や例外オブジェクトの継承ツリーで区別をつけてると思います
LogicExeptionを継承する例外ととRuntimeExceptionを継承する例外とか
> >>617
> そのGoogleのC++スタイルガイドに「C++の例外は使いません。」と明記されているのか。
> これはGoogleが正しい。
Googleがそうやっているだけで、それがベストプラクティスとは限りません
>>611 のコードにエラーログ出力を追加しようとしたらひと苦労です
> スタックトレースまで必要になるならば、それはエラーではなくプログラムのバグだろう。
エラーが発生した場所がどこであるのかが例外オブジェクトに含まれているなら、スタックトレースが不要な場合もあるかもしれませんが、あればどういう呼び出しのときにエラーが発生したのかわかるので便利です
> その区別を付けたほうが好ましい。
大抵の場合は例外の種別や例外オブジェクトの継承ツリーで区別をつけてると思います
LogicExeptionを継承する例外ととRuntimeExceptionを継承する例外とか
> >>617
> そのGoogleのC++スタイルガイドに「C++の例外は使いません。」と明記されているのか。
> これはGoogleが正しい。
Googleがそうやっているだけで、それがベストプラクティスとは限りません
>>611 のコードにエラーログ出力を追加しようとしたらひと苦労です
621デフォルトの名無しさん
2022/01/13(木) 18:20:01.16ID:YmYunxX5 Googleのスタイルガイドでは、C++の例外は雑に扱えないぐらいには面倒だしメリットがそこまで大きくもない、って書いてるぐらいで、例外は不要だとは断じてないよね
面倒だからGoogleの巨大なレガシーコードには今更例外を導入できないし、それが依存する可能性のあるプロジェクトにも例外は使わせたくない、って感じでしょ
面倒だからGoogleの巨大なレガシーコードには今更例外を導入できないし、それが依存する可能性のあるプロジェクトにも例外は使わせたくない、って感じでしょ
622デフォルトの名無しさん
2022/01/13(木) 18:27:00.76ID:2BXAobev623デフォルトの名無しさん
2022/01/13(木) 18:31:49.09ID:E5YlFTVp >>622
話がずれていってるけど、大本の話題はこれだからね
> プログラミングにおいて、エラー処理のためのtry catch例外処理は本来不要なものである。
> エラーは関数の戻り値で返せばよい。
あと、軽く調べたが、googleはSTLもboostも基本使えないみたいよ
もちろん、例外をthrowするサードパーティ製ライブラリも使えない
修行僧みたいw
話がずれていってるけど、大本の話題はこれだからね
> プログラミングにおいて、エラー処理のためのtry catch例外処理は本来不要なものである。
> エラーは関数の戻り値で返せばよい。
あと、軽く調べたが、googleはSTLもboostも基本使えないみたいよ
もちろん、例外をthrowするサードパーティ製ライブラリも使えない
修行僧みたいw
624デフォルトの名無しさん
2022/01/13(木) 18:33:20.28ID:E5YlFTVp あと、Microsoftは違うスタンスみたいだよ
https://docs.microsoft.com/ja-jp/cpp/cpp/errors-and-exception-handling-modern-cpp?view=msvc-170
> 最新の C++ のほとんどのシナリオでは、論理エラーとランタイム エラーの両方を報告および処理する方法として、例外を使用することが推奨されます。 特に、エラーを検出する関数と、エラーを処理するコンテキストを持つ関数の間に複数の関数呼び出しがスタックに含まれている可能性がある場合に当てはまるとします。 例外は、エラーを検出して情報を呼び出し履歴に渡すコードに関する、正しく定義された正式な方法を提供します。
https://docs.microsoft.com/ja-jp/cpp/cpp/errors-and-exception-handling-modern-cpp?view=msvc-170
> 最新の C++ のほとんどのシナリオでは、論理エラーとランタイム エラーの両方を報告および処理する方法として、例外を使用することが推奨されます。 特に、エラーを検出する関数と、エラーを処理するコンテキストを持つ関数の間に複数の関数呼び出しがスタックに含まれている可能性がある場合に当てはまるとします。 例外は、エラーを検出して情報を呼び出し履歴に渡すコードに関する、正しく定義された正式な方法を提供します。
625デフォルトの名無しさん
2022/01/13(木) 18:52:55.65ID:2BXAobev626デフォルトの名無しさん
2022/01/13(木) 19:13:49.01ID:E5YlFTVp >>625
> プログラムのバグとエラー(=入出力や相手次第で発生)の両方を、ごっちゃに同じ例外で扱ってる自覚はあるわけだ。
そもそも、アプリケーションプログラマバグによる例外のthrowはほぼ書かないと思いますけどね
バグ由来の「異常発生」には、ほぼ誰も気にしてないと思うよ(もちろん、最終的な処理が必要なら書くけど)
> いずれにせよMicrosoftもRustに積極的だから、時間をかけて脱C++へ進んでいることに変わりはない。
多分、30年は無理じゃないかな(個人の感想です)
Java, C++がでてきてからもう30年くらい?かな
COBOLやFORTRANの生き残り具合を鑑みるとそう思えます
https://www.tiobe.com/tiobe-index/
Fortran 19位
COBOL 25位
Rust 26位 ← 思ったより検討してた
> プログラムのバグとエラー(=入出力や相手次第で発生)の両方を、ごっちゃに同じ例外で扱ってる自覚はあるわけだ。
そもそも、アプリケーションプログラマバグによる例外のthrowはほぼ書かないと思いますけどね
バグ由来の「異常発生」には、ほぼ誰も気にしてないと思うよ(もちろん、最終的な処理が必要なら書くけど)
> いずれにせよMicrosoftもRustに積極的だから、時間をかけて脱C++へ進んでいることに変わりはない。
多分、30年は無理じゃないかな(個人の感想です)
Java, C++がでてきてからもう30年くらい?かな
COBOLやFORTRANの生き残り具合を鑑みるとそう思えます
https://www.tiobe.com/tiobe-index/
Fortran 19位
COBOL 25位
Rust 26位 ← 思ったより検討してた
627デフォルトの名無しさん
2022/01/13(木) 19:25:42.66ID:DCVQhT4S Rustの利点はわかったけど、?演算子とpanicは例外の発展形にしか見えないなぁ。
(?演算子でエラー移譲を受けた)呼び出し元は、エラーを無視してもpanicしなくて済むのかしらん?
エラーを処理しなきゃいけないんだったら例外と大して変わらん気がする。
(?演算子でエラー移譲を受けた)呼び出し元は、エラーを無視してもpanicしなくて済むのかしらん?
エラーを処理しなきゃいけないんだったら例外と大して変わらん気がする。
628デフォルトの名無しさん
2022/01/13(木) 19:47:20.65ID:sBBuaSsw 例外は危険。
使うべからず。
使うべからず。
629デフォルトの名無しさん
2022/01/13(木) 19:47:53.64ID:2BXAobev >>626
単なる通信エラーにすぎなくてもtry catchの例外で受ける例はあるよね。
>>606のデータベースアクセスの例だと、DBサーバーとの通信時エラーが起きるとfoo()は例外を投げることになる。
しかも例外を投げるのはfoo()自身ではなく、そこから呼ぶDBサーバ通信部分だったり、そこから呼ぶ汎用通信ライブラリだったり、誰が例外を投げるかわからない。
>>627
今書いている関数で例外が発生するのかどうか、奥底まで追わないとはっきりしないデメリットが例外にはある。
?演算子を使えば、下からエラーが来ていて上へエラー処理を移譲していることが明確になる。
あと、質問に対する答えは、main()関数までもがさぼってResultを返せば、自分でエラー処理をせずともエラー表示される。
単なる通信エラーにすぎなくてもtry catchの例外で受ける例はあるよね。
>>606のデータベースアクセスの例だと、DBサーバーとの通信時エラーが起きるとfoo()は例外を投げることになる。
しかも例外を投げるのはfoo()自身ではなく、そこから呼ぶDBサーバ通信部分だったり、そこから呼ぶ汎用通信ライブラリだったり、誰が例外を投げるかわからない。
>>627
今書いている関数で例外が発生するのかどうか、奥底まで追わないとはっきりしないデメリットが例外にはある。
?演算子を使えば、下からエラーが来ていて上へエラー処理を移譲していることが明確になる。
あと、質問に対する答えは、main()関数までもがさぼってResultを返せば、自分でエラー処理をせずともエラー表示される。
630デフォルトの名無しさん
2022/01/13(木) 20:16:47.27ID:Pln9PLvq631デフォルトの名無しさん
2022/01/13(木) 21:01:12.03ID:QuitFgmw >>627
エラー処理はそんな大変なことではなく例えば
if let Ok(value) = foo() {
bar(value);
}
と正常値の時だけ処理したりも出来る
正常値を得るにはif letやmatchやその他にResult型のメソッドなどを必ず使わないと正常値を取り出せないので
Rustではエラー値なのにチェック忘れで突き進むバグが生じないのも利点
エラー処理はそんな大変なことではなく例えば
if let Ok(value) = foo() {
bar(value);
}
と正常値の時だけ処理したりも出来る
正常値を得るにはif letやmatchやその他にResult型のメソッドなどを必ず使わないと正常値を取り出せないので
Rustではエラー値なのにチェック忘れで突き進むバグが生じないのも利点
632デフォルトの名無しさん
2022/01/13(木) 21:59:08.34ID:W/MOMDn7 Rust全くわかってないんだけどOkはマクロ?
633デフォルトの名無しさん
2022/01/13(木) 22:10:33.52ID:7TJ/z3m3634デフォルトの名無しさん
2022/01/13(木) 22:14:53.71ID:7TJ/z3m3635デフォルトの名無しさん
2022/01/13(木) 22:26:16.24ID:+PFReeTS >>570
>大半のアプリケーションでは個別にハンドリングせず
>集約エラーハンドラに任せたいとエラーのほうが圧倒的多数だから
どこでなぜ起きたかわからないエラーをキャッチしてもなぁ。
erlangのlet it crashのようにエラーの種類は考慮しないってんならわからんでもないけど。
>大半のアプリケーションでは個別にハンドリングせず
>集約エラーハンドラに任せたいとエラーのほうが圧倒的多数だから
どこでなぜ起きたかわからないエラーをキャッチしてもなぁ。
erlangのlet it crashのようにエラーの種類は考慮しないってんならわからんでもないけど。
636デフォルトの名無しさん
2022/01/13(木) 22:36:17.73ID:2BXAobev >>632
Okはenumの識別子。
Result型はenumでありOk(正常値)とErr(エラー値)のどちらかになる。
enumといってもRustは識別子に付随する値を持つこともできる。
つまりC/C++には無い新たな枠組みで、これがRustを強力にしている一つ。
>>630
try catchは関数呼び出しが多段になった時に、
途中の関数ではtry catchもthrowも出てこないから情報がなく気付けない。
Rustは途中の関数で?オペレータを必ず付けるから、
エラーが起きる可能性があることを必ず認識できる。
>>631
Resultに対して多数のメソッドがあって短くエラー処理できる点もいいね。
例えば以下の2つは同じで、エラー時にDEFAULT_VALUEとなる。
let a = foo().unwrap_or(DEFAULT_VALUE);
let a = if let Ok(value) = foo() { value } else { DEFAULT_VALUE };
以下の2つも同じで、エラー時にクロージャ |err| bar(err) の値となる。
let b = foo().unwrap_or_else(|err| bar(err));
let b = match foo() {
Ok(value) => value,
Err(err) => |err| bar(err),
};
Okはenumの識別子。
Result型はenumでありOk(正常値)とErr(エラー値)のどちらかになる。
enumといってもRustは識別子に付随する値を持つこともできる。
つまりC/C++には無い新たな枠組みで、これがRustを強力にしている一つ。
>>630
try catchは関数呼び出しが多段になった時に、
途中の関数ではtry catchもthrowも出てこないから情報がなく気付けない。
Rustは途中の関数で?オペレータを必ず付けるから、
エラーが起きる可能性があることを必ず認識できる。
>>631
Resultに対して多数のメソッドがあって短くエラー処理できる点もいいね。
例えば以下の2つは同じで、エラー時にDEFAULT_VALUEとなる。
let a = foo().unwrap_or(DEFAULT_VALUE);
let a = if let Ok(value) = foo() { value } else { DEFAULT_VALUE };
以下の2つも同じで、エラー時にクロージャ |err| bar(err) の値となる。
let b = foo().unwrap_or_else(|err| bar(err));
let b = match foo() {
Ok(value) => value,
Err(err) => |err| bar(err),
};
637デフォルトの名無しさん
2022/01/13(木) 22:40:25.51ID:t/cn/0uo >>588
bad_allocは絶対発生しないシステムなの?
bad_allocは絶対発生しないシステムなの?
638デフォルトの名無しさん
2022/01/13(木) 22:56:39.62ID:FqgOTQou >>635
集約エラーハンドラは汎用のエラー画面表示やログ出力のためだぞ
例外の中身を見ればどこでなぜ起きたかはわかるがユーザーには対処できないものを扱う
Erlangは軽量プロセス単位のリトライなので全然違う
集約エラーハンドラは汎用のエラー画面表示やログ出力のためだぞ
例外の中身を見ればどこでなぜ起きたかはわかるがユーザーには対処できないものを扱う
Erlangは軽量プロセス単位のリトライなので全然違う
639デフォルトの名無しさん
2022/01/13(木) 23:29:52.77ID:+PFReeTS >集約エラーハンドラは汎用のエラー画面表示やログ出力のためだぞ
例外マンセー軍全員こう思ってる?
参ったw
例外マンセー軍全員こう思ってる?
参ったw
640デフォルトの名無しさん
2022/01/14(金) 00:04:27.93ID:InXswW/0 >>631
戻り値無し(副作用目的)で失敗する可能性のある関数もチェック忘れ防げるようになってたっけ?
戻り値無し(副作用目的)で失敗する可能性のある関数もチェック忘れ防げるようになってたっけ?
641デフォルトの名無しさん
2022/01/14(金) 00:14:04.94ID:0aNzNV+4 例外が嫌いすぎて例外使ったことないエアプだから、頓珍漢なことしか言えない
議論する価値ないわ
議論する価値ないわ
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- ミス・ユニバース フィンランド代表の「つり目」写真が波紋… 本人釈明も批判やまず 協会謝罪「徹底的に検証」へ [冬月記者★]
- 自民・麻生太郎副総裁 石破政権の1年は「どよーん」 高市政権発足で「何となく明るくなった」「世の中のことが決まり動いている」★2 [Hitzeschleier★]
- 【おこめ券】鈴木憲和農相 小泉前農相の備蓄米放出を“反省”「備蓄の円滑な運営を図ってまいります」 [Hitzeschleier★]
- 1人3千円の食品高騰対策、何に使える? あいまいなまま衆院通過 [蚤の市★]
- ゆたぼん 二重手術を報告「めちゃくちゃ気に入っています」 [muffin★]
- 【山形】クマ駆除で誤射した猟友会隊員に町が1663万円請求へ...弾当たり男性大けが2023年 小国町 [nita★]
- 中国人、ガチ超正論。「日本人がアイヌに対してやったことを『問題ない』とするなら、中国が日本人に同じことをしても文句ないだろう?」 [314039747]
- 【悲報】新米、全く売れなくて倉庫が満杯になってしまうwwwwwwwwwwwwwwwwwwww [802034645]
- 木曜日のんなっしょい❗(・o・🍬)仕放題スレ🏡
- 【悲報】日本共産党、ツイッター速報にブチギレ法的措置WWWWWWWWWWWWWWWWWWWWWWWWWWWW [935793931]
- 官僚「台湾有事についての質問か、『政府として逐一答えない』と…(カタカタカタ)」高市「私1人で答弁できるわよ!」 [972432215]
- 【悲報】麻生太郎さん、オムツをしていた。晋さん…ここにいたんだね… [731544683]
