競え
※前スレ
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:biBE4xC0610デフォルトの名無しさん
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 例外が嫌いすぎて例外使ったことないエアプだから、頓珍漢なことしか言えない
議論する価値ないわ
議論する価値ないわ
642デフォルトの名無しさん
2022/01/14(金) 00:14:49.01ID:Gws88Xz4 >>640
正常系の戻り値がない関数なら戻り値はResult<(),Error>になって、これを無視するとwarningが出るから気付く
正常系の戻り値がない関数なら戻り値はResult<(),Error>になって、これを無視するとwarningが出るから気付く
643デフォルトの名無しさん
2022/01/14(金) 00:19:25.76ID:fGcmjtxY >>640
まず関数の戻り型はResult<(), Error>となる
()はRustで戻り値なしを意味しタプル0個と覚えれる
次にその関数を普通にfoo();と呼び出すコードを書く
すると「使われていないResult値がある」とコンパイラに警告される
したがってエラー値チェックを忘れていることに気付ける
まず関数の戻り型はResult<(), Error>となる
()はRustで戻り値なしを意味しタプル0個と覚えれる
次にその関数を普通にfoo();と呼び出すコードを書く
すると「使われていないResult値がある」とコンパイラに警告される
したがってエラー値チェックを忘れていることに気付ける
644デフォルトの名無しさん
2022/01/14(金) 00:20:04.51ID:InXswW/0 >>642
おー、ほんとだ。いいね。
https://doc.rust-lang.org/src/core/result.rs.html#71-75
> //! A common problem with using return values to indicate errors is
> //! that it is easy to ignore the return value, thus failing to handle
> //! the error. [`Result`] is annotated with the `#[must_use]` attribute,
> //! which will cause the compiler to issue a warning when a Result
> //! value is ignored. ...
おー、ほんとだ。いいね。
https://doc.rust-lang.org/src/core/result.rs.html#71-75
> //! A common problem with using return values to indicate errors is
> //! that it is easy to ignore the return value, thus failing to handle
> //! the error. [`Result`] is annotated with the `#[must_use]` attribute,
> //! which will cause the compiler to issue a warning when a Result
> //! value is ignored. ...
645デフォルトの名無しさん
2022/01/14(金) 13:50:52.20ID:CyyU39UP >>629
> 今書いている関数で例外が発生するのかどうか、奥底まで追わないとはっきりしないデメリットが例外にはある。
今書いている関数では、ハンドリングする例外に着目するだけでいいんだが
(何を言ってるのかわからんかもしれんが)
> 今書いている関数で例外が発生するのかどうか、奥底まで追わないとはっきりしないデメリットが例外にはある。
今書いている関数では、ハンドリングする例外に着目するだけでいいんだが
(何を言ってるのかわからんかもしれんが)
646デフォルトの名無しさん
2022/01/14(金) 13:52:22.52ID:CyyU39UP647デフォルトの名無しさん
2022/01/14(金) 13:55:14.01ID:CyyU39UP Googleのコーディング規約が神だと思ってるみたいだが、発表された当時内容があまりにアレだったので界隈がざわついた記憶がある
組み込み関連は知らんが、それ以外でGoogleのコーディング規約を取り入れてるところはないんじゃないか
組み込み関連は知らんが、それ以外でGoogleのコーディング規約を取り入れてるところはないんじゃないか
648デフォルトの名無しさん
2022/01/14(金) 14:37:16.30ID:B7zHdTDq 参考にしてるのは業務でまともにC++を使ったことがない素人ばかりかもね
649デフォルトの名無しさん
2022/01/14(金) 14:45:16.44ID:Ml4XYYXN >>629
> 今書いている関数で例外が発生するのかどうか、奥底まで追わないとはっきりしないデメリットが例外にはある。
逆にRustだとなんかの理由で奥底の関数がエラーを返すように変更されたらその上の関数全てを変更するってこと?
> 今書いている関数で例外が発生するのかどうか、奥底まで追わないとはっきりしないデメリットが例外にはある。
逆にRustだとなんかの理由で奥底の関数がエラーを返すように変更されたらその上の関数全てを変更するってこと?
650デフォルトの名無しさん
2022/01/14(金) 15:08:09.78ID:CyyU39UP Rust始めたばかりだからまだよくわかってないが、エラー処理周りのこと調べると、まだまだ迷走中な感じだな
少なくとも初手から言語仕様として完璧なエラー処理構造が入ってたわけではないことがわかった
Rust のエラーまわりの変遷
https://qiita.com/legokichi/items/d4819f7d464c0d2ce2b8
少なくとも初手から言語仕様として完璧なエラー処理構造が入ってたわけではないことがわかった
Rust のエラーまわりの変遷
https://qiita.com/legokichi/items/d4819f7d464c0d2ce2b8
651デフォルトの名無しさん
2022/01/14(金) 15:14:13.63ID:fGcmjtxY >>649
まず一般的にどの言語であっても奥底の関数の仕様が変更されたらそれを吸収できるところは変更となる
次にエラーが起きない関数が突然にエラーが起きるようにはならないのでそんな仕様変更は起きない
入出力相手があるものは初めからエラーが起きうることがわかるしメモリ上の操作だけであってもsearchやmatchなど成否が起きうるものも最初からわかっている
まず一般的にどの言語であっても奥底の関数の仕様が変更されたらそれを吸収できるところは変更となる
次にエラーが起きない関数が突然にエラーが起きるようにはならないのでそんな仕様変更は起きない
入出力相手があるものは初めからエラーが起きうることがわかるしメモリ上の操作だけであってもsearchやmatchなど成否が起きうるものも最初からわかっている
652デフォルトの名無しさん
2022/01/14(金) 15:21:48.16ID:/o+2ilkb 「そんな仕様変更は起きない」ということはなく、普通にAPIの設計ミスっててやっぱりエラーになる可能性あった、というのはありうる
その場合Rustならコンパイルエラーで気付くが、例外だとこれまで例外出さなかった関数が急に出すようになるわけで、なかなか厳しいね
その場合Rustならコンパイルエラーで気付くが、例外だとこれまで例外出さなかった関数が急に出すようになるわけで、なかなか厳しいね
653デフォルトの名無しさん
2022/01/14(金) 15:24:49.44ID:Ml4XYYXN >>651
> まず一般的にどの言語であっても奥底の関数の仕様が変更されたらそれを吸収できるところは変更となる
例外なら途中の関数の変更は不要だよ
> 次にエラーが起きない関数が突然にエラーが起きるようにはならないのでそんな仕様変更は起きない
お前さんの妄想は要らんよ
> 入出力相手があるものは初めからエラーが起きうることがわかるしメモリ上の操作だけであってもsearchやmatchなど成否が起きうるものも最初からわかっている
計算だけしかしない関数が外部に計算させるように変更されたらどうするの?
> まず一般的にどの言語であっても奥底の関数の仕様が変更されたらそれを吸収できるところは変更となる
例外なら途中の関数の変更は不要だよ
> 次にエラーが起きない関数が突然にエラーが起きるようにはならないのでそんな仕様変更は起きない
お前さんの妄想は要らんよ
> 入出力相手があるものは初めからエラーが起きうることがわかるしメモリ上の操作だけであってもsearchやmatchなど成否が起きうるものも最初からわかっている
計算だけしかしない関数が外部に計算させるように変更されたらどうするの?
654デフォルトの名無しさん
2022/01/14(金) 15:28:08.59ID:Ml4XYYXN >>652
> 例外だとこれまで例外出さなかった関数が急に出すようになるわけで、なかなか厳しいね
例外出すように変更したら当然それを受けるように変更するでしょ?
例外なら発生と受けるところの変更だけで済むけど、Rustだと間の関数も全て変更が必要じゃね?
> 例外だとこれまで例外出さなかった関数が急に出すようになるわけで、なかなか厳しいね
例外出すように変更したら当然それを受けるように変更するでしょ?
例外なら発生と受けるところの変更だけで済むけど、Rustだと間の関数も全て変更が必要じゃね?
655デフォルトの名無しさん
2022/01/14(金) 15:34:01.30ID:B7zHdTDq try-catchは素人にはうまく使えないよなあ、とは思う
656デフォルトの名無しさん
2022/01/14(金) 15:36:58.27ID:bXd4RL2X てかエラー処理全般、本気でやるとしたら世の中でできるやつはかなり限られてる。
GAFAとか含めてもそう。
GAFAとか含めてもそう。
657デフォルトの名無しさん
2022/01/14(金) 15:37:15.18ID:/o+2ilkb >>654
自分で変更したとしても、それを使っている箇所を漏れなく変更できるか?という問題もあるし
ましてや依存ライブラリの仕様変更だったらどうするの?という話
誰もがCHANGELOGを正しく書いてくれるわけではないし、見落としだってある
自分で変更したとしても、それを使っている箇所を漏れなく変更できるか?という問題もあるし
ましてや依存ライブラリの仕様変更だったらどうするの?という話
誰もがCHANGELOGを正しく書いてくれるわけではないし、見落としだってある
658デフォルトの名無しさん
2022/01/14(金) 15:44:57.54ID:fGcmjtxY659デフォルトの名無しさん
2022/01/14(金) 15:51:24.55ID:Ml4XYYXN660デフォルトの名無しさん
2022/01/14(金) 16:03:30.57ID:/o+2ilkb661デフォルトの名無しさん
2022/01/14(金) 16:16:10.98ID:Ml4XYYXN 面倒というより本質的に途中の関数には関係ないはずなのに修正が必要になると言うのがちょっと嫌かな
まあ現状ではmore betterなんだろうけどなんとか洗練されないものかと
まあ現状ではmore betterなんだろうけどなんとか洗練されないものかと
662デフォルトの名無しさん
2022/01/14(金) 16:27:26.86ID:WRwvxAen >>659
外部サーバーに計算させるよう変更するには
まずその外部のIPアドレスかホスト名かそれらを含むURIなどが新たなパラメタとして引数に入る
途中の関数があるとすれば全て影響を受けるだろう
さらにそのようなことが必要な規模の計算の場合
外部サーバーを使わずとも自分のところでも並列計算をしていたはずである
また計算以外も含めて今どきはマルチスレッド利用が前提とすると
スレッド間の例外は不可もしくは例外を使わず受け渡しをして投げ直すことになる
結局これは例外を使わない場合と同じことをせざるをえなくなる
外部サーバーに計算させるよう変更するには
まずその外部のIPアドレスかホスト名かそれらを含むURIなどが新たなパラメタとして引数に入る
途中の関数があるとすれば全て影響を受けるだろう
さらにそのようなことが必要な規模の計算の場合
外部サーバーを使わずとも自分のところでも並列計算をしていたはずである
また計算以外も含めて今どきはマルチスレッド利用が前提とすると
スレッド間の例外は不可もしくは例外を使わず受け渡しをして投げ直すことになる
結局これは例外を使わない場合と同じことをせざるをえなくなる
663デフォルトの名無しさん
2022/01/14(金) 16:39:58.04ID:Ml4XYYXN >>662
> まずその外部のIPアドレスかホスト名かそれらを含むURIなどが新たなパラメタとして引数に入る
クラスとか使ったことないのかな?
> 外部サーバーを使わずとも自分のところでも並列計算をしていたはずである
はずはず君w
もう少し考えてからレスしないと恥の上塗りにしかなってないよ
> まずその外部のIPアドレスかホスト名かそれらを含むURIなどが新たなパラメタとして引数に入る
クラスとか使ったことないのかな?
> 外部サーバーを使わずとも自分のところでも並列計算をしていたはずである
はずはず君w
もう少し考えてからレスしないと恥の上塗りにしかなってないよ
664デフォルトの名無しさん
2022/01/14(金) 16:45:29.34ID:eFXg0S3t >>662
計算じゃなく、データベースにクエリー投げるとか普通にあるだろ。 そういう場合、
いちいち関数の引数にIPアドレスやホスト名を渡すのではなく、オブジェクトメンバ
として持たせて、計算メソッドを呼ぶって実装にするのでは?
んで、サーバー応答がない場合だけでなく、IPアドレスやホスト名をセットせずに、
計算メソッドを呼んだりしたら、例外を投げるよな?
計算じゃなく、データベースにクエリー投げるとか普通にあるだろ。 そういう場合、
いちいち関数の引数にIPアドレスやホスト名を渡すのではなく、オブジェクトメンバ
として持たせて、計算メソッドを呼ぶって実装にするのでは?
んで、サーバー応答がない場合だけでなく、IPアドレスやホスト名をセットせずに、
計算メソッドを呼んだりしたら、例外を投げるよな?
665デフォルトの名無しさん
2022/01/14(金) 16:46:26.60ID:CyyU39UP >>658
> 途中で低位層の仕様が変わるとか有り得ない机上の空論に対して
> どこまで何を前提にしていいのか何もかも不明だから誰も何も答えられない
やっぱり例外のことわかってないね
自作関数hoge()がサードパーティ製ライブラリの関数foo()を呼び出しているとき、hoge()ではfoo()が送出する例外をどうするかを実装するだけでいい
その後、foo()が更新されfoo()が依存するライブラリが例えばIoErrorをthrowするようになってfoo()はそれに対して何もしないとしても、hoge()は変更する必要がないし知る必要もない
> 途中で低位層の仕様が変わるとか有り得ない机上の空論に対して
> どこまで何を前提にしていいのか何もかも不明だから誰も何も答えられない
やっぱり例外のことわかってないね
自作関数hoge()がサードパーティ製ライブラリの関数foo()を呼び出しているとき、hoge()ではfoo()が送出する例外をどうするかを実装するだけでいい
その後、foo()が更新されfoo()が依存するライブラリが例えばIoErrorをthrowするようになってfoo()はそれに対して何もしないとしても、hoge()は変更する必要がないし知る必要もない
666デフォルトの名無しさん
2022/01/14(金) 16:48:22.67ID:fGcmjtxY 並行並列処理した時点で例外が破綻するのは事実だな
擬似的に例外を伝播させるにしても途中でエラー値渡しが必要
例外を使えば途中は何も考えなくていいはウソだな
擬似的に例外を伝播させるにしても途中でエラー値渡しが必要
例外を使えば途中は何も考えなくていいはウソだな
667デフォルトの名無しさん
2022/01/14(金) 16:55:06.25ID:CyyU39UP そもそも、例えばJavaScriptでnpmパッケージを少しつかうと、数百個のnpmパッケージがインストールされて数千個のthrowが実装されてて、全貌を知るなんて無理んだんだよ
そんなこと知らなくても、JavaScriptでアプリコードは書ける
そんなこと知らなくても、JavaScriptでアプリコードは書ける
668デフォルトの名無しさん
2022/01/14(金) 16:56:04.83ID:Ml4XYYXN >>666
スレッド内では関数を多段に呼び出すことはないという主張なのかな?
スレッド内では関数を多段に呼び出すことはないという主張なのかな?
669デフォルトの名無しさん
2022/01/14(金) 16:57:10.80ID:CyyU39UP やっぱこいつ例外のことなんもわかってねーわ
670デフォルトの名無しさん
2022/01/14(金) 16:59:50.72ID:WRwvxAen671デフォルトの名無しさん
2022/01/14(金) 17:02:36.16ID:8BRe3wDd >>665
知らなくていいメリットか知りようがないデメリットか
知らなくていいメリットか知りようがないデメリットか
672デフォルトの名無しさん
2022/01/14(金) 17:02:40.51ID:fGcmjtxY673デフォルトの名無しさん
2022/01/14(金) 17:03:04.21ID:CyyU39UP 例外がわかってないっつーか
プログラミングど素人だったわw
プログラミングど素人だったわw
674デフォルトの名無しさん
2022/01/14(金) 17:10:08.74ID:aHL9Oj90 >>654
そうだよ
Tで返してたところをOption<T>で返すように変更が入るとかは普通にある
型で表現できることのメリットの裏返しで
型で表現してるからこそそれに依存してるところは全部変更が必要
誰か書いてたけど検査例外と同じデメリットがある
そうだよ
Tで返してたところをOption<T>で返すように変更が入るとかは普通にある
型で表現できることのメリットの裏返しで
型で表現してるからこそそれに依存してるところは全部変更が必要
誰か書いてたけど検査例外と同じデメリットがある
675デフォルトの名無しさん
2022/01/14(金) 17:13:19.40ID:aHL9Oj90 >>665
これはRustでも同じ
hoge()ではfoo()が返すResult<T, E>のErrorだけ気にすればいいように作る
(正確にはfooを含むmod Fooが定義するErrorのうちfooが返すものだけ気にする)
これはRustでも同じ
hoge()ではfoo()が返すResult<T, E>のErrorだけ気にすればいいように作る
(正確にはfooを含むmod Fooが定義するErrorのうちfooが返すものだけ気にする)
676デフォルトの名無しさん
2022/01/14(金) 17:13:47.97ID:WRwvxAen >>665
JavaScriptについてちゃんとわかっていないようだな
それらは大量にあっても自分のところに飛んで来ないthrowだ
自分のところに飛んでくるthrowはcatchしないとuncaughtExceptionで怒られる
だから下から例外が来るか否かは把握していないといけない
そもそも途中でライブラリの仕様が変わって例外を投げるようになること自体がナンセンスだが
JavaScriptについてちゃんとわかっていないようだな
それらは大量にあっても自分のところに飛んで来ないthrowだ
自分のところに飛んでくるthrowはcatchしないとuncaughtExceptionで怒られる
だから下から例外が来るか否かは把握していないといけない
そもそも途中でライブラリの仕様が変わって例外を投げるようになること自体がナンセンスだが
677デフォルトの名無しさん
2022/01/14(金) 17:26:27.30ID:fGcmjtxY >>667
まずは例外の基本を理解しなさい
ライブラリ群のソースの中に何千個のthrowがあろうが各々のtry-catchで閉じ込められておりその外に対しては一切無関係
関係があるのは自分に向かって来る分のみ
まずは例外の基本を理解しなさい
ライブラリ群のソースの中に何千個のthrowがあろうが各々のtry-catchで閉じ込められておりその外に対しては一切無関係
関係があるのは自分に向かって来る分のみ
678デフォルトの名無しさん
2022/01/14(金) 17:43:36.82ID:UhvSPNNm679デフォルトの名無しさん
2022/01/14(金) 17:45:12.30ID:UhvSPNNm >>672
整理できてないのは お・ま・え w
整理できてないのは お・ま・え w
680デフォルトの名無しさん
2022/01/14(金) 17:48:13.03ID:UhvSPNNm681デフォルトの名無しさん
2022/01/14(金) 18:00:55.12ID:fGcmjtxY682デフォルトの名無しさん
2022/01/14(金) 19:16:22.53ID:kUhlpB/h そもそもrustで言うと Result<T, E> の E を変更するのは破壊的変更だから普通は依存crateのエラー型をそのまま外部に見せるようなことはしない
683デフォルトの名無しさん
2022/01/14(金) 19:42:59.80ID:7uXlwHnS684デフォルトの名無しさん
2022/01/14(金) 19:49:44.98ID:fGcmjtxY685デフォルトの名無しさん
2022/01/14(金) 20:30:51.27ID:TehXI+gA コードの修正が必要になるって話な
> 逆にRustだとなんかの理由で奥底の関数がエラーを返すように変更されたらその上の関数全てを変更するってこと?
> 逆にRustだとなんかの理由で奥底の関数がエラーを返すように変更されたらその上の関数全てを変更するってこと?
686デフォルトの名無しさん
2022/01/14(金) 20:46:13.89ID:WRwvxAen >>685
エラーに限らず一般的によくあることだね
返すべき値が増えたり
返すべき型が変わったり
あるいは逆に
引き渡す値が増えたり
引き渡す型が変わったり
それらは機能追加変更でも起きるけど
リファクタリングでも起きたりしてる
Rustでも他の言語でもその状況は変わらない
エラーに限らず一般的によくあることだね
返すべき値が増えたり
返すべき型が変わったり
あるいは逆に
引き渡す値が増えたり
引き渡す型が変わったり
それらは機能追加変更でも起きるけど
リファクタリングでも起きたりしてる
Rustでも他の言語でもその状況は変わらない
687デフォルトの名無しさん
2022/01/14(金) 21:26:13.10ID:9EKaNxsm 話の流れ見えてる?
> 例外なら発生と受けるところの変更だけで済むけど、Rustだと間の関数も全て変更が必要じゃね?
> 面倒というより本質的に途中の関数には関係ないはずなのに修正が必要になると言うのがちょっと嫌かな
> 例外なら発生と受けるところの変更だけで済むけど、Rustだと間の関数も全て変更が必要じゃね?
> 面倒というより本質的に途中の関数には関係ないはずなのに修正が必要になると言うのがちょっと嫌かな
688デフォルトの名無しさん
2022/01/14(金) 21:29:54.99ID:qeE4Uiz1689デフォルトの名無しさん
2022/01/14(金) 21:33:39.15ID:8BRe3wDd どこでどういう例外が発生するか全部把握している人にとっては造作もないこと
690デフォルトの名無しさん
2022/01/14(金) 21:40:25.58ID:WRwvxAen691デフォルトの名無しさん
2022/01/14(金) 21:52:56.30ID:kQdsKxlC692デフォルトの名無しさん
2022/01/14(金) 22:00:42.61ID:0UR5WO3U >?オペレーターで飛ばす途中の関数はそのまま変更ないよ
?オペレーターかどうかは関係ないやろ
いつもいつもホントいい加減な事言うよなぁ
?オペレーターかどうかは関係ないやろ
いつもいつもホントいい加減な事言うよなぁ
693デフォルトの名無しさん
2022/01/14(金) 22:16:08.15ID:WRwvxAen694デフォルトの名無しさん
2022/01/14(金) 22:28:31.33ID:Rec6pgsK 検査例外の不便さを軽減しつつ例外が送出されることのみ型で明記する方式をとったのがSwift
RustのResultを返す方式と基本思想は同じだがエラーの型を明記しなくていいので使いやすい
RustのResultを返す方式と基本思想は同じだがエラーの型を明記しなくていいので使いやすい
695デフォルトの名無しさん
2022/01/14(金) 22:32:28.06ID:8BRe3wDd エラーの種類を型で区別するというのがそもそも無理があったんだろうな。
696デフォルトの名無しさん
2022/01/14(金) 22:35:46.65ID:WRwvxAen697デフォルトの名無しさん
2022/01/14(金) 22:45:19.38ID:/e6eXz55698デフォルトの名無しさん
2022/01/14(金) 22:53:53.91ID:WRwvxAen699デフォルトの名無しさん
2022/01/15(土) 00:46:19.46ID:2yxrsW1B 言語が違うんだからやり方や考え方が違うというのはべつにどうでもよくて
どちらの方がバグを生みにくいのかが気になる
エラーハンドリングにまつわるバグもいろいろあるけど、例えばリカバリ可能なエラーを取り逃してプログラムがクラッシュする可能性が低いのはどっちなの?
どちらの方がバグを生みにくいのかが気になる
エラーハンドリングにまつわるバグもいろいろあるけど、例えばリカバリ可能なエラーを取り逃してプログラムがクラッシュする可能性が低いのはどっちなの?
700デフォルトの名無しさん
2022/01/15(土) 02:37:29.52ID:p6KpEKbL メモリがないとパニックしてabortってなんなの?
動作変えられないの?
動作変えられないの?
701デフォルトの名無しさん
2022/01/15(土) 02:40:42.88ID:+D8ShBal >>699
それならばRustが安全
Rustのenum Result型から正常値を取り出すには
matchやif letもしくはResult型のメソッドunwrap_*()などの
エラー値ではない時のみ正常値を取り出し使える手段を必ず経る必要がある
つまり正常値を使って処理していくコードはエラー値ではない時だけしか動作しないことが保証される
それならばRustが安全
Rustのenum Result型から正常値を取り出すには
matchやif letもしくはResult型のメソッドunwrap_*()などの
エラー値ではない時のみ正常値を取り出し使える手段を必ず経る必要がある
つまり正常値を使って処理していくコードはエラー値ではない時だけしか動作しないことが保証される
702デフォルトの名無しさん
2022/01/15(土) 08:12:31.52ID:f2+KU74o >>698
常識と言いながら話をループさせるのはもしかして認知症… w
常識と言いながら話をループさせるのはもしかして認知症… w
703デフォルトの名無しさん
2022/01/15(土) 08:49:08.65ID:2yxrsW1B >>701エラーケースのリカバリの話をしているんだが
704デフォルトの名無しさん
2022/01/15(土) 09:29:13.90ID:qyAynvOh705デフォルトの名無しさん
2022/01/15(土) 09:44:44.45ID:GF5575Ny ここはrustをよく知らない人に
rust初心者がrustをゴリ押しするスレです。
rust初心者がrustをゴリ押しするスレです。
706デフォルトの名無しさん
2022/01/15(土) 09:46:20.74ID:l/1QpEiq >>699
強いて言えばRustかな
強いて言えばRustかな
707デフォルトの名無しさん
2022/01/15(土) 10:05:00.72ID:l/1QpEiq できるだけコンパイル時にチェックしてくれるほうが良い。
708デフォルトの名無しさん
2022/01/15(土) 10:09:23.43ID:CrZ3UR5p >>699
JavaやSwiftみたいに検査例外があるやつはRustと大差ないだろうね
非検査例外しかないやつだとcatch忘れるのを防げないが
あとはfinallyやdeferによるエラー時の後始末は忘れる可能性があるが、RustならRAIIに任せられる範囲内でなら忘れない
JavaやSwiftみたいに検査例外があるやつはRustと大差ないだろうね
非検査例外しかないやつだとcatch忘れるのを防げないが
あとはfinallyやdeferによるエラー時の後始末は忘れる可能性があるが、RustならRAIIに任せられる範囲内でなら忘れない
709デフォルトの名無しさん
2022/01/15(土) 10:10:14.51ID:zYbpVr1V 日本語初心者でもありそう
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 自民・麻生太郎 副総裁 石破政権の1年は「どよーん」 高市政権の発足で「何となく明るくなった」「世の中のことが決まり動いている」 [Hitzeschleier★]
- 東京都「都民の税金1.5兆円が国に奪われている」「全国に分配されている」に地方民ブチギレ [Hitzeschleier★]
- JA全農が「新おこめ券」…来年9月末の有効期限を新設、必要経費のみ上乗せ [蚤の市★]
- 「もうキモくてキモくて…」29歳女性が語る“おぢアタック”の実態。「俺ならイケるかも」年下女性を狙う勘違い中年男性に共通点が★4 [Hitzeschleier★]
- 【27歳会社員】「自慰行為に使うために」コインランドリーの乾燥機から24歳女性の下着など計11点(時価8万2080円相当)盗んだ疑い [nita★]
- 1人3千円の食品高騰対策、何に使える? あいまいなまま衆院通過 [蚤の市★]
- トランプ、G7に代わるcore 5を発表 [805596214]
- イ カ れ た メ ン バ ー 紹 介 す る ぜ !
- 【実況】博衣こよりのえちえちダンガンロンパ2🧪★5
- 為末大「ラーメン屋の行列を、年寄りが1万円渡してきて順番譲ってくれと言ったら? 答えられない問題だよ。」 [592058334]
- 【悲報】日本共産党、ツイッター速報にブチギレ法的措置WWWWWWWWWWWWWWWWWWWWWWWWWWWW [935793931]
- 【実況】博衣こよりのえちえちダンガンロンパ2🧪★4
