[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 2ch.scのread.cgiへ]
Update time : 02/11 13:46 / Filesize : 165 KB / Number-of Response : 546
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

Rust part19



1 名前:デフォルトの名無しさん mailto:sage [2023/01/17(火) 12:41:32.25 ID:nikBFIMQ.net]
公式
https://www.rust-lang.org/
https://blog.rust-lang.org/
https://github.com/rust-lang/rust

公式ドキュメント
https://www.rust-lang.org/learn

Web上の実行環境
https://play.rust-lang.org

※Rustを学びたい人はまず最初に公式のThe Bookを読むこと
https://doc.rust-lang.org/book/

※Rustを学ぶ際に犯しがちな12の過ち
https://dystroy.org/blog/how-not-to-learn-rust

※Rustのasyncについて知りたければ「async-book」は必読
https://rust-lang.github.io/async-book/

※次スレは原則>>980が立てること

前スレ
Rust part18
https://mevius.5ch.net/test/read.cgi/tech/1670663822/

2 名前:デフォルトの名無しさん mailto:sage [2023/01/17(火) 12:41:51.84 ID:esjs4yiD.net]
たておつ

3 名前:デフォルトの名無しさん mailto:sage [2023/01/17(火) 14:00:56.91 ID:MqwPrlrO.net]
89 それでも動く名無し 2023/01/10(火) 23:26:51.53 ID:pA5+SQtP0
痴漢ものAVと違ってこういうガチ痴漢は臨場感が違うわ
抵抗されて上手く行かなかったり、たまに他の客にバレて逃走してるからな
マジで興奮する
https://i.imgur.com/My4nuB1.jpg
https://i.imgur.com/ttXkWGH.jpg
https://i.imgur.com/upphmaU.jpg
https://gcolle.net/product_info.php/products_id/763929/ref/15062/affiliate_banner_id/1

520 名無しさん@ピンキー sage 2023/01/03(火) 21:36:57.85 ID:AS4vmq4R0
不朽の名作が復活していたので
https://i.imgur.com/SGsDTp5.jpg
https://i.imgur.com/4R20ojB.jpg
https://gcolle.net/product_info.php/products_id/863650/ref/15062/affiliate_banner_id/1

4 名前:デフォルトの名無しさん mailto:sage [2023/01/17(火) 14:01:08.20 ID:MqwPrlrO.net]
すみません、誤爆しました

5 名前:デフォルトの名無しさん mailto:sage [2023/01/17(火) 14:04:39.15 ID:QD1aLS8A.net]
   . :::';;;;: . .     ..,,,;;:
   . . :;;;;;:.:;;,,    ..:.;;;;.:
   :;;'''  .:';;; . .  .:.:;;;;;':. . .        .,,,,;,,...,,
      .:;;;' :   .:;;;;; .: ,,,;;;,,,   ,  .:;;;';;''' ''';;;;,,
     . :.;;;;' . .:   ;;;;;;;;'''' ';;;:.:.. ,;: . .    ''''''"
     ';;:;'     '''';   .:.';;;;,,;;.
                 '''  ,.:.:';;;;,,,,
             ,、—-、    .;.';:;.:.: ;;;;;;:.;.;...
   -、_      (_二ニ=っ,、;;;:.:;.:;...:.:...'''''''''''
     `‐-、_  (  ´∀)f、 `''、:..:.:. .:
         `-,ノ   つ; /
         (〇  〈-`'"
         (_,ゝ  ) `‐-、_
           (__)     `'‐-、,_..
                        `‐-、._

6 名前:デフォルトの名無しさん mailto:sage [2023/01/17(火) 14:25:12.33 ID:IvlgRnTP.net]
ここが新しいおちんぽスレと聞いて

7 名前:デフォルトの名無しさん [2023/01/17(火) 14:31:29.73 ID:AjT+2M0N.net]
最低だな
犯罪者予備軍やん

8 名前:デフォルトの名無しさん mailto:sage [2023/01/17(火) 16:35:46.70 ID:+0g0VEsU.net]
通報しといたよ

9 名前:デフォルトの名無しさん mailto:sage [2023/01/17(火) 16:41:04.96 ID:mmIRzxLT.net]
はよ立て直せ

10 名前:デフォルトの名無しさん mailto:sage [2023/01/18(水) 10:59:16.69 ID:j7LzfbP6.net]
ワッチョイ有効スレ
https://mevius.5ch.net/test/read.cgi/tech/1674007100/



11 名前:デフォルトの名無しさん mailto:sage [2023/01/18(水) 12:30:23.66 ID:NvrWVfIW.net]
おちんぽまんまんスレ違いと聞いて

12 名前:デフォルトの名無しさん mailto:sage [2023/01/18(水) 20:15:50.70 ID:CRD98AUE.net]
ResultがErrの時だけブロックを実行するifってどうやって書けばいいの?
if Err(_) = fs::read_to_string("foo.txt") { err() }
は通らないようだが

13 名前:デフォルトの名無しさん mailto:sage [2023/01/18(水) 20:29:34.91 ID:vXgVoSzN.net]
if let Err(_)

14 名前:デフォルトの名無しさん mailto:sage [2023/01/18(水) 20:41:58.72 ID:CRD98AUE.net]
>>13
サンキュー。行けた

15 名前:デフォルトの名無しさん mailto:sage [2023/01/19(木) 04:27:00.05 ID:UpsgRjC+.net]
>>12
エラーが起きた時は先に判断してreturnして
そうでなく正常値が得られた時はlet代入してインデントを下げずに書けないかな?

16 名前:デフォルトの名無しさん mailto:sage [2023/01/19(木) 07:51:52.20 ID:kHXiKnOP.net]
>>15
それが少し前に入ってみんな喜んでた let else だね。

let Ok(value) = result else { return };
/* Ok のときやりたい処理 */

みたいにエラーは早期リターンして、正常系をインデント下げて書くみたいなことができる。

俺は Err は anyhow で呼び出し側に返しちゃう事が多いから正直あまり使わないけど。

17 名前:デフォルトの名無しさん [2023/01/19(木) 10:36:41.67 ID:pws6L0p3.net]
Option/Result系は?演算子で素直に返すしそれ以外でもResultを返す関数に切り出して呼び出し側で?演算子にするからlet-elseは使い所がよく分からん

18 名前:デフォルトの名無しさん mailto:sage [2023/01/19(木) 11:05:24.00 ID:MVgEnHGb.net]
>>15
そもそもreturnしない。err()の中身はエラーメッセージを出力後にパニックさせるので一方通行

19 名前:デフォルトの名無しさん [2023/01/19(木) 13:52:46.10 ID:i8wJP128.net]
expectじゃだめなのかな?
もう少しちゃんとしたロギングをしたいならlog crate使ってlog_expectみたいな形でunwrap

20 名前:デフォルトの名無しさん [2023/01/19(木) 14:21:48.46 ID:plizw9iy.net]
自分で書いといてあれだからやっばりexpect使うケースじゃないな
panicさせるよりもErrのまま最上位まで返してそこでログ出力含めてハンドリング



21 名前:デフォルトの名無しさん mailto:sage [2023/01/19(木) 18:44:58.53 ID:kHXiKnOP.net]
expectってライブラリの動作確認とかサンプルコードとか、トップレベルで雑なことしたいとき以外使わなくない?

深めの階層で見かけたら身構えちゃいそう。

22 名前:デフォルトの名無しさん mailto:sage [2023/01/19(木) 19:25:25.54 ID:UlqzrrZi.net]
論理的に安全にunwrapできるってわかってる箇所には使うかな
もしパニックになるならそもそも致命的な論理バグがあるってことになるから
変にエラー処理するより早期に落とした方がいいってケース

23 名前:デフォルトの名無しさん mailto:sage [2023/01/19(木) 20:03:32.07 ID:KyLvYp+m.net]
横からですまんが安全なら unwrap() でよくない?
expect() にする理由ってなんだろう

24 名前:デフォルトの名無しさん mailto:sage [2023/01/19(木) 20:30:48.24 ID:UlqzrrZi.net]
個人的には Regex::new(r"").unwrap() みたいに自明ならunwrap
安全にunwrapできる理由を書きたいならコメントに書くよりexpectに書くかな

25 名前:デフォルトの名無しさん mailto:sage [2023/01/19(木) 20:45:59.09 ID:kHXiKnOP.net]
なるほどね。自明な時に unwrap したいけど、仮に起きたときに原因調査しやすいよう expect というのは納得できる。

26 名前:デフォルトの名無しさん mailto:sage [2023/01/19(木) 20:51:26.80 ID:kHXiKnOP.net]
あ、違うか。unwrapできる理由を書くわけか。

paniced at 'ここでは 0 は渡ってこないので自信を持って除算する'

みたいな出力になるから割と恥ずかしいな。

27 名前:デフォルトの名無しさん mailto:sage [2023/01/19(木) 21:03:13.60 ID:KyLvYp+m.net]
>>26
これは俺も思ったw
まぁ自分しか使わないライブラリとかならいいかもね

28 名前:はちみつ餃子 mailto:sage [2023/01/19(木) 22:24:19.09 ID:uAmZfzQm.net]
>>27
自分意外が使う前提のときのほうが except が必要だと思う。

外部から与えられる情報が仕様外の場合 (事前条件が満たされない場合) など
使い方が誤っているときに起こりえるなら except で説明があったほうがいいんじゃない?

内部的なロジック的に起こりえないと確信しているところは unwrap でいいと思う。
間違いがあったときに panic! してくれることには変わりないしバックトレースも出せるんで、
特に必要だと思う箇所だけ説明を付けておけば十分でしょ。

29 名前:デフォルトの名無しさん mailto:sage [2023/01/19(木) 22:58:51.51 ID:TbDEskmg.net]
>>26
関係ないけどpanicに-ed、-ingつけるとkが差し込まれてpanicked、panickingになる
自分もRust触るまで知らなかった

30 名前:デフォルトの名無しさん mailto:sage [2023/01/20(金) 00:14:17.87 ID:+VmzUJ32.net]
Optionを返す関数が2つ(以上)あり、
Someを得られるまで遅延評価で順に試す場合に、
func1(arg)
.or_else(|| func2(arg))
と非対称で手間なのを改善する方法ありますか?
例えば func1(arg) || func2(arg) と書けると便利だと思いました



31 名前:デフォルトの名無しさん mailto:sage [2023/01/20(金) 00:47:21.47 ID:sbzTb5wM.net]
イテレータ化してchain()で繋げるとか?
でも手間は変わらないか

32 名前:デフォルトの名無しさん [2023/01/20(金) 02:52:18.79 ID:rWEP7xyW.net]
>>30
ないんじゃね
何回も書く必要があるなら単に関数化する
||演算子で書きたければマクロ内独自文法作る

33 名前:デフォルトの名無しさん mailto:sage [2023/01/20(金) 11:05:21.77 ID:cF/QvtGv.net]
>>20
今だいたいそうなっていてmainにエラー出力用のコードが散在している状態
エラーメッセージの出力先もコンソールのみじゃないのでexpectだと難しい気が

34 名前:デフォルトの名無しさん mailto:sage [2023/01/20(金) 13:36:20.52 ID:pmLm7hT0.net]
ちんちん!シュッ!シュッ!!シュッ!!!

35 名前:デフォルトの名無しさん [2023/01/20(金) 21:59:08.95 ID:A12k25he.net]
>>33
いろんな問題をごちゃ混ぜにしすぎ
頭とコードを整理しよう

36 名前:デフォルトの名無しさん mailto:sage [2023/01/21(土) 14:16:15.90 ID:tEFzN85r.net]
1.すべてmainまで返してmainでエラー処理をする
2.エラー処理用の関数を作ってそれを呼び出す
3.パニックハンドラでエラーメッセージを出力
くらいしか思いつかん。ググってもThe Bookに書いてある程度のことしか出てこなくて参考にならない
3はpanic!やexpectで脱出できるのは楽だけどハンドラへ渡せるデータが文字列のみでなのがいまいち
またエラー処理に必要な情報を文字列にエンコードする必要がある
2ならmainまで戻らずともエラー処理できるのでこの方向で実装中

37 名前:デフォルトの名無しさん [2023/01/21(土) 14:57:31.49 ID:hb5eMxVX.net]
log crateやtrace crateはチェック済み?
logは準標準、実装は好きなのを選ぶ必要がある
traceはtokio-rs製

38 名前:デフォルトの名無しさん mailto:sage [2023/01/21(土) 16:41:16.71 ID:3Tq4pZe4.net]
>>32
|オペレータのstd::ops::BitOrトレイトのように
||オペレータのトレイトをRustコンパイラが用意してくれたらOptionも||で扱えそう

39 名前:デフォルトの名無しさん mailto:sage [2023/01/21(土) 18:30:23.18 ID:/bIQjlWu.net]
>>37
info!やerror!ってpanic!やexpectと本質的に変わらないような。いずれにしろ呼び出し側で文字列の加工が必要
GUIへの対応方法もよくわからない。開発時はもちろんコンソールへの出力を使うけど
運用中のエラー出力はGUIのポップアップメッセージがメインになるし

あとソースコードは600行弱くらいだけどリリースビルドで生成されるバイナリは800KB弱もあるんで
これ以上でかくしたくないというのもある

40 名前:デフォルトの名無しさん [2023/01/21(土) 22:40:10.67 ID:wag66I/R.net]
ロガーを設定/生成するコード
ロガーを使うコード
ロガー自体のコード
それぞれ分けて考える

ロガーを使うコードではファイル出力だろうが標準出力だろうがinfo!やerror!でコードを変える必要はない
使うロガーを変えたり設定を変えたりする

ロギングライブラリを使うのは自前で作るのは面倒だから



41 名前:デフォルトの名無しさん [2023/01/22(日) 02:33:12.00 ID:5IaN6zUW.net]
書籍で最初に読むとしたら
平家蟹の方?
それとも可愛い方?

42 名前:デフォルトの名無しさん mailto:sage [2023/01/22(日) 02:45:54.00 ID:DAK16wxY.net]
平家蟹がかわいくないとか、こいつアンチか?

43 名前:デフォルトの名無しさん [2023/01/22(日) 02:46:40.77 ID:4BdfAMug.net]
>>39
>GUIへの対応方法もよくわからない。
GUIのレイヤーまでResultを戻してErrならエラー表示をするだけ

44 名前:デフォルトの名無しさん mailto:sage [2023/01/22(日) 12:43:00.06 ID:WLCvNrGP.net]
>>39
ログはログ。何が起きたか記録するだけ。ログレベルが何であれ副作用は起こさない。
エラーはエラー。発生したときにどうハンドリングするかはプログラムの性質で決める。
パニックはそのまま稼働したらまずい状況に陥ったら時だけ起こす。

45 名前:デフォルトの名無しさん [2023/01/22(日) 14:52:04.22 ID:RMpOCJx1.net]
>>41
モンタギュー蟹の方

46 名前:デフォルトの名無しさん [2023/01/22(日) 15:29:33.81 ID:WCVJRVcD.net]
アプリケーションのレイヤーでパニック起こすのはバグの時だけ

47 名前:デフォルトの名無しさん mailto:sage [2023/01/25(水) 16:19:44.22 ID:zlgPT3s2.net]
ネットワーク前提にしてる時に、panicになるのはバグではないよ?

48 名前:デフォルトの名無しさん mailto:sage [2023/01/25(水) 16:35:00.31 ID:LG3Fy/yw.net]
うっわすっげー読みやすいコードと思ってよく見てみたら
過去に自分が書いたやつだった(´・ω・`)

49 名前:デフォルトの名無しさん mailto:sage [2023/01/25(水) 16:39:27.19 ID:5onhVltK.net]
天才か?

50 名前:デフォルトの名無しさん mailto:sage [2023/01/25(水) 16:40:49.73 ID:GSIKYco3.net]
過去の自分は他人だと思え、がプログラミングの基本



51 名前:デフォルトの名無しさん mailto:sage [2023/01/25(水) 17:17:39.71 ID:xORIlv/9.net]
過去のことを忘れていても過去の自分が考えることは今の自分が考えることとあまり差がない。
名前の付け方とかは何度考えても同じような状況なら同じ名前を付けるし。

書くときに想定する読み手が全くの他人のときと未来の自分のときではちょっと違う意識があるな。

52 名前:デフォルトの名無しさん mailto:sage [2023/01/25(水) 18:36:03.64 ID:V9gmFqbx.net]
一度も使ったことがない機能は書くことはできても読めると思うな、が基本
使ってから読め

53 名前:デフォルトの名無しさん mailto:sage [2023/01/25(水) 19:53:08.97 ID:sck5kayB.net]
>>47
ネットワークこそ途中で途切れること前提に書かないといけない機能の最たるものだろ。エラー返してハンドリングしろ。

54 名前:デフォルトの名無しさん [2023/01/25(水) 20:37:11.28 ID:5EKz9Dxo.net]
>>48
あるあるだね

55 名前:デフォルトの名無しさん [2023/01/25(水) 20:38:19.94 ID:xtWPaGBn.net]
>>47
なんでpanicになるの?

56 名前:デフォルトの名無しさん mailto:sage [2023/01/25(水) 21:43:02.36 ID:jK9fbSTx.net]
>>38
一度ポシャってるけど実装される可能性はあると思う
https://github.com/rust-lang/libs-team/issues/144

57 名前:デフォルトの名無しさん mailto:sage [2023/01/25(水) 23:55:49.39 ID:7h2BZmgN.net]
bool以外でも&&と||の遅延評価が使えるようになるわけか
欲しいね

58 名前:デフォルトの名無しさん mailto:sage [2023/01/26(木) 00:47:59.28 ID:Oik+f0Gv.net]
bool以外でもifを使えるといえばif letで
elseを省略することで3項ではなく2項演算のようになるのも&&と同じ
だがelseを省略できても{}を省略できなければ意味がない

59 名前:デフォルトの名無しさん [2023/01/26(木) 11:05:43.50 ID:G0iCERKY.net]
>>58
もうちょっと基礎を勉強してからレスしろ

60 名前:デフォルトの名無しさん [2023/01/26(木) 11:09:10.89 ID:QY5r5/0E.net]
すまんが、これの解答はmutをつけろっていうことなのはわかるけどさ
https://github.com/rust-lang/rustlings/blob/main/exercises/variables/variables4.rs
なんで8行目で所有権を失って9行目で代入できなくなったりしないの・・・・?



61 名前:デフォルトの名無しさん [2023/01/26(木) 11:24:13.84 ID:DDvWU5a2.net]
>>60
これはもっともな疑問

The Bookのどこかに書いてたように思うけど
ざっくり言えばprintlnはreferenceを取るから所有権は移動しない

DisplayトレイトやDebugトレイトのメソッドシグニチャを見ると分かる

62 名前:デフォルトの名無しさん mailto:sage [2023/01/26(木) 11:33:53.75 ID:Y60o/Mze.net]
>>60
ついこないだ Teratail で同じような質問を見たぞ。
マクロは構文糖を作り出す仕組みなので展開形によっては所有権を取ることも借用なことも何にも使いすらしないということもある。

63 名前:デフォルトの名無しさん mailto:sage [2023/01/26(木) 14:03:27.91 ID:YuUaXpq9.net]
ある関数の&mut T型の引数として、T型の変数を貸すのは分かるけど
&mut T型の変数を又貸しするのが不思議
なぜmoveしたことにならないのか

64 名前:デフォルトの名無しさん mailto:sage [2023/01/26(木) 15:25:17.84 ID:MCrVnhV0.net]
>>63
&TはCopyだからmoveしないよ

65 名前:デフォルトの名無しさん [2023/01/26(木) 15:35:28.34 ID:SkvAt80a.net]
>>63
implicit reborrowのことかな?
&mut Tの又貸しと言ってるのがどういうケースなのかはコードかないハッキリはわからないな

66 名前:デフォルトの名無しさん mailto:sage [2023/01/26(木) 17:21:49.46 ID:YuUaXpq9.net]
implicitly reborrowedされるとhogeが&mut *hogeになるのか
勉強になった
ありがとう

67 名前:デフォルトの名無しさん mailto:sage [2023/01/26(木) 18:45:49.05 ID:nglgEIPC.net]
結局&mutを持っている間は専有しているから既存ルールに抵触することなく貸し出し自由自在という理解でいいのかな
&*でimmutableなreborrowも出来ちゃうもんね

68 名前:デフォルトの名無しさん mailto:sage [2023/01/26(木) 19:48:43.33 ID:16g2h/GU.net]
>>60
変数が値を所有しているんだよ
値がムーブされて一度無効化された変数にも新しい値を所有させられるよ
例えば、その9行目でxが3を所有していなかったとしても新しい値を入れられるよ
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=657d792c80f30e9430f0fbff11556fe6

69 名前:デフォルトの名無しさん mailto:sage [2023/01/26(木) 19:50:53.34 ID:uBPDOaY+.net]
暗黙で参照が外されることがあるからわかりにくいんだろうな
最初から暗黙の参照外しがなければよかったと思うが
後方互換性を大事にするなら、もう改善は不可能だな

70 名前:デフォルトの名無しさん mailto:sage [2023/01/26(木) 20:31:02.62 ID:q1WzF/2m.net]
>>53
だからバグじゃないよね?



71 名前:デフォルトの名無しさん [2023/01/26(木) 21:11:51.00 ID:BacNCpeu.net]
>>70
エラーを返すんだからpanicしないだろ

72 名前:デフォルトの名無しさん [2023/01/26(木) 21:14:28.71 ID:GObOayQz.net]
>>68
そりゃmutならなw

73 名前:デフォルトの名無しさん [2023/01/26(木) 21:18:17.56 ID:q8T2WGhT.net]
implicit reborrowはThe Bookには書かれないし直感的でもないから動きが理解しにくいというのはよく分かる

74 名前:デフォルトの名無しさん mailto:sage [2023/01/26(木) 21:50:47.31 ID:ZxPs9rBQ.net]
>>70
例えばtwitterアプリを地下鉄とか通信できない状況で起動して panic で落ちる事を考えてみろ。そりゃバグだろ。

75 名前:デフォルトの名無しさん mailto:sage [2023/01/26(木) 22:06:21.53 ID:HEA6MC1t.net]
Deref無しは流石にきついな
一気にRust書きたくなくなる気がする

76 名前:デフォルトの名無しさん mailto:sage [2023/01/26(木) 22:20:38.36 ID:nglgEIPC.net]
>>69
むしろderef含めたcoercionのおかげでRustは便利かつ読みやすいと思う
初心者の最初のうちだけは混乱するかもしれないけどそのデメリットを誤差にするほどの絶大なメリットがある

77 名前:60 [2023/01/27(金) 11:24:22.85 ID:CSClNfzp.net]
教えてくれてるのは本当にありがたいんですが、訳がわかんないぽ・・・・

78 名前:デフォルトの名無しさん [2023/01/27(金) 11:51:57.32 ID:YDsF+xqw.net]
>>77
何がわからないのか書いて

79 名前:60 [2023/01/27(金) 13:58:30.55 ID:CSClNfzp.net]
マクロが展開するコードがあって、そこに&がついてるってことなんですか?

80 名前:デフォルトの名無しさん mailto:sage [2023/01/27(金) 14:00:09.55 ID:MqPTrKVr.net]
せやで
Playgroundの左上のボタンでShow HIRするとマクロ展開等終わった後のコード出るから見てみ



81 名前:デフォルトの名無しさん mailto:sage [2023/01/27(金) 19:13:43.59 ID:q2LYouLt.net]
&はついてるけどあなたの疑問とは関係ないと思う

82 名前:デフォルトの名無しさん mailto:sage [2023/01/27(金) 21:29:03.39 ID:N1uoRX56.net]
>>74
例がtwitterアプリって...通信が出来ない状態でも何らかのオフライン操作が行えるアプリであればそうでしょうが
仕様上、エラーハンドリングを行わなければならないとされていないならバグではないでしょ....
むしろ大したログやコンソールでの情報も出さず、「エラー:通信ができましぇん」なんて返されるほうが迷惑だわ

83 名前:デフォルトの名無しさん mailto:sage [2023/01/27(金) 21:54:30.76 ID:cQ0vJjwr.net]
>>82
バグかどうかは仕様次第というのはそりゃそうなんだけど、それじゃ建設的な議論にならんでしょ。
俺はError返しといたほうが利用側がハンドリングする余地があっていいと思うね。

84 名前:はちみつ餃子 mailto:sage [2023/01/28(土) 02:45:04.16 ID:OM0pptP0.net]
>>82
Rust の文化にあまり詳しいわけじゃないけど panic を呼び出すのって C/C++ で言うところの assert 的なもんでしょ。
普通に考えたら panic が呼ばれるのはモジュールの仕様に対して使い方が間違っているかリカバリ不可能な場合。
逆に言えば使い方が正しくてリカバリ可能な状況で panic になるべきではない。

モジュールの使い方が完璧に正しいプログラムを書いても panic が引き起こされてしまうなら panic の使い方のほうが間違ってる。
絶対に通信が確立する状況で使えという仕様を設定すりゃあ間違ってるのは使い方のほうではあるけどさー、
ネットワークでそれは不可能な前提じゃん? ありえない前提を元にするのは不毛だろ。

85 名前:デフォルトの名無しさん mailto:sage [2023/01/28(土) 07:46:19.92 ID:NqcfPhRT.net]
>>82
> 仕様上、エラーハンドリングを行わなければならないとされていないならバグではないでしょ....
仕様バグ...

86 名前:デフォルトの名無しさん mailto:sage [2023/01/28(土) 09:58:07.00 ID:40nYh31B.net]
ユーザーにとって不自然な動作をすれば開発者が仕様だと言い張ったところでそれはバグだよ

87 名前:デフォルトの名無しさん mailto:sage [2023/01/28(土) 10:54:36.16 ID:9JWZ6Tol.net]
エラーにも回復可能なエラーと不可能なエラーがあり、panicすると回復不可能な状態になるんだから、回復可能なエラーはpanicすべきじゃない。ましてや通常使用でしばしば発生する状態でpanicするのは言語道断だわな。

88 名前:デフォルトの名無しさん mailto:sage [2023/01/28(土) 10:57:15.78 ID:A5TUrW0u.net]
assertというかexitやな。推奨はされん、普通はデバッグで面倒な時くらいじゃないか。

89 名前:デフォルトの名無しさん mailto:sage [2023/01/28(土) 11:52:23.17 ID:NqcfPhRT.net]
>>86
MSの開発者を説得してくれ

90 名前:デフォルトの名無しさん mailto:sage [2023/01/28(土) 11:54:06.56 ID:NqcfPhRT.net]
>>88
exitは正常終了でも呼ばれるからassertのほうが意味的には近いと思うぞ



91 名前:デフォルトの名無しさん mailto:sage [2023/01/28(土) 14:06:35.25 ID:qTYDIi6E.net]
マルチスレッド界隈ではスレッドの一つや二つ終了しても
回復不可能と思ってないでしょ

92 名前:デフォルトの名無しさん [2023/01/28(土) 14:59:51.08 ID:pTjpQsNq.net]
The Bookにある回復不可能かどうかという判断基準は曖昧であまり役に立たない

Resultを伝播させてトップレベルでログ出力でもしてabortさせるのに比べて
問題発生箇所でpanicさせるメリットは処理をinfallibleな関数として定義出来ること

逆に言えばバグでも無いのにinfallibleな関数呼び出しでpanicで落ちるような設計はそれ自体がバグの可能性大

93 名前:デフォルトの名無しさん mailto:sage [2023/01/28(土) 17:20:49.61 ID:qTYDIi6E.net]
0か1かではなくバグが何個あるのかも重要
落とせば一つ?
進めれば二つ以上?

94 名前:デフォルトの名無しさん [2023/01/28(土) 17:59:00.91 ID:b6xT90Ev.net]
>>93
イミフ

95 名前:デフォルトの名無しさん mailto:sage [2023/01/28(土) 19:43:12.93 ID:qTYDIi6E.net]
>>86
開発者なんていないよ、みんなユーザーだよって言い張ったのがオープンソースだね

96 名前:デフォルトの名無しさん [2023/01/28(土) 21:12:57.88 ID:ZIiiTUHL.net]
>>95
イミフ その3

97 名前:デフォルトの名無しさん mailto:sage [2023/01/28(土) 22:16:55.89 ID:qTYDIi6E.net]
ユーザーと開発者を分断して対立煽るのをやめようってことだよ

98 名前:デフォルトの名無しさん mailto:sage [2023/01/28(土) 23:41:24.90 ID:j4/fJAgO.net]
自分(たち)で用いるツール類だけは
自明な前提を満たしていない場合に限り
エラー処理をサボったpanicで終わらせてもよい

それ以外のpanicは状態矛盾など続行不可禁止で発生するが
正しくエラー終了させるべきものであり
panic発生はバグと呼んでも差し支えない

99 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 01:28:33.47 ID:K5ah9cLk.net]
>>98
panicをハンドリングしないのはバグかどうかは仕様次第と完全に認めてるのに、建設的な議論って・・・
作法的な話や、ユーザーフレンドリなUIでエラーメッセージを出したい、いきなり終了して欲しくないのであってもプロジェクトごとに異なるし、一般的な普遍性なんて「仕様上」に何が言いようがあるんだ?
オレはいつもこうしてます!という癖だったらいくらでも言えるし、100人集めてアプリケーションのレイヤーでpanicをハンドリングする/しないでアンケートしてどっちが人気かで正しさが決まるようなものではない。
最終的に「アプリケーションのレイヤーでパニック起こすのはバグの時だけ」とかいうのは明らかに間違ってるでしょ
そうするような特定のプロジェクトの仕様がたまたま(確率的に)一致するかもしれないが、それも一般化できる話ではないよ。

まあ、お望みの建設的な議論をするなら、アプリケーションをライブラリのように使用できる余地があるならResultsなどでErrorを返すのはとても良いですが、それでもpanicをハンドリングしてErrorで返すべきでは”無い”でしょうね
なぜならRustはそれを推奨していないし、Errorチェックしてをpanicに変換する方向性はあっても、panicをErrorに変える方向性は、仮にログ出力してもpanicの握り潰しやエラー情報の欠落に等しい。(なぜならログへのI/Oエラーになってる可能性もあるから)
それは、そもそもRustのpanicは言葉上は回復不能なエラーであり、バグではなくメモリーに物理的な障害が発生して配列インデックスが変になったとか、処理が続行できない、もしくはいったん特定の場所に戻って回復できないときに使われる思想。
なので、panic->Error変換処理が正常に働くかも怪しい。だからRustはそれを捉えず上位へ流して最低限やるスタックの巻き戻しのみ処理を推奨し、即座に終了させる(=プログラムが落ちる)
Linusはこのスタックの自動巻き戻しがとても気に入らないらしいが、理由は巻き戻し処理が正常に働く理由が無いからだ。
それを無理やり捉えて、スタックトレースが出るのが嫌、即座に終了するのが嫌、は分かるけどpanicで終了したからと言って仕様に書いてなければバグじゃないでしょ

これを癖でやってしまうのはtry-catch構文があるC#やJava系から来た人が多いのではないかな...?

100 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 02:35:07.62 ID:r5isV+tS.net]
誰もpanicをResultに変換する話はしとらんやろ



101 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 07:18:58.36 ID:ksaPk66E.net]
て言うか>>99は前半と後半で矛盾してるしアホほど長文を証明してるw

102 名前:デフォルトの名無しさん [2023/01/29(日) 11:17:47.92 ID:p51Kojpz.net]
panicは仕様に書いてなければバグでしょ
どんなプログラム書いてんだよ

103 名前:デフォルトの名無しさん [2023/01/29(日) 11:27:06.90 ID:FaEg6ckP.net]
エラーハンドリングという言葉をpanicをハンドリングしてResultにすることだと思ってたのか
そりゃ噛み合わないわな

104 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 13:10:21.68 ID:ZDOIjMr/.net]
例えばpythonのexitの代用としてpanicを使ったところで何の問題もない

105 名前:デフォルトの名無しさん [2023/01/29(日) 14:45:33.86 ID:ttNbSKVN.net]
問題ありまくり
同じexitがあるのにわざわざpanicで代用するメリットは何?

106 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 15:29:55.13 ID:yzACUqHq.net]
まずは異常終了と正常終了を分断するメリットを知る必要がある

107 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 15:33:47.16 ID:ZDOIjMr/.net]
>>105
へー今初めて知った
The BookのCommon Programming Conceptsあたりにそれっぽい記述はないし
中断したければpanicするしかないと思っていたよ
後学のためにどこで解説されているのか教えてほしいな

108 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 15:48:49.58 ID:CZoRokqJ.net]
panic!すべきかするまいか
https://doc.rust-jp.rs/book-ja/ch09-03-to-panic-or-not-to-panic.html

109 名前:デフォルトの名無しさん [2023/01/29(日) 17:07:54.00 ID:qjfBPBdR.net]
>>107
The Bookの12章を復習して
https://doc.rust-lang.org/book/ch12-00-an-io-project.html

ただThe Bookは他言語から来た人が最初に読むチュートリアルとして用意されてるものなのでカバーされてない内容も多々あるし深い解説がされてるわけでもない点は理解しておいた方がいいよ

110 名前:はちみつ餃子 mailto:sage [2023/01/29(日) 17:16:49.84 ID:2OIx0YXk.net]
標準ライブラリのマニュアルでも panic! はバグを説明するために使うということは書いてあるね。
https://doc.rust-lang.org/std/macro.panic.html



111 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 18:20:40.83 ID:yP5ym/xP.net]
>>107
exitはプロセスの終了状態コードを伝えることを兼ねたOSシステムコールだから通常の言語には必ずある
そしてそのことを分かっていればRust初心者であってもstd::process::exitをすぐに見つけられる

112 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 18:41:07.89 ID:qSgQK/Ke.net]
>>105
Pythonのsys.exitと同じ感覚でstd::process::exit使うほうがはるかに問題では?
少なくとも異常終了に使う分にはpanic!のほうがsys.exitに近いと思うよ

sys.exit()
https://docs.python.org/3/library/sys.html#sys.exit
・SystemExit例外を投げるだけ
・メインスレッドで実行して、かつ例外がトップレベルまで捕捉されなければ、通常の例外機構に従ってプロセスが終了する
→finallyとかwithでリソース解放書けばちゃんと解放される

std::process::exit()
https://doc.rust-lang.org/std/process/fn.exit.html
・無条件でプロセスを終了させる
・実行スレッドも他のスレッドも一切スタック巻き戻しが行われない
→デストラクタ呼ばれない

113 名前:デフォルトの名無しさん [2023/01/29(日) 18:45:14.86 ID:jE2G9ZiM.net]
_exit()はシステムコールだけどexit()はライブラリの関数
pythonのexit()やsys.exit()は基本的にexitcodeを設定してSystemExit例外を投げてるだけ
os._exit()がprocess::exit()に近い

114 名前:デフォルトの名無しさん [2023/01/29(日) 18:46:31.90 ID:jE2G9ZiM.net]
>>112
例外のある言語と同じ感覚でプログラミングするのが一番の問題
それ抜きにpythonと比べとも意味ないよ

115 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 18:48:13.88 ID:yP5ym/xP.net]
一般的な他の言語におけるtry-throw-catchの機能が欲しいならば
それはRustやGoなどでは意図的に排除されていて存在しない
RustではResultで返すだけでよく利便性と効率を両立させている

116 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 19:53:25.69 ID:ZDOIjMr/.net]
>>109
そこは見ているけど制御機構を説明しているところで同時に解説すべきなのでは

>The Bookは他言語から来た人が最初に読むチュートリアルとして用意されてるもの
なおさら他言語でメジャーな機能や実装と対比した解説が必要では

>>112
unwind不可なのは使いにくい場面が少なからずありそう
今作っているのはdrop使っているから強制abortは問題しかない

117 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 21:27:11.45 ID:yzACUqHq.net]
RustのdropにはRcという具体的な目的がある
Rcが完璧主義ではないのでdropも完璧にする必要を感じない

118 名前:デフォルトの名無しさん [2023/01/29(日) 21:32:58.27 ID:ns31yZLJ.net]
>>112
>Pythonのsys.exitと同じ感覚でstd::process::exit使うほうがはるかに問題では?

RustではResultをmainまで戻してからprocess::exitする
Pythonは例外という仕組みでランタイムがそれをやってくれる
panicはやってることがにてるからという理由で使うようなものじゃない

119 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 21:46:05.85 ID:hfoWSJ8/.net]
>>115
そうではないよ?例えばrustの標準ライブラリのTcpStreamにはset_read_timeoutでタイムアウトを設定すると、それ設定値以上でpanicを起こす。
これは通信中に非同期制御やスレッド監視などをしないための苦肉の策でResultをmatchするだけという考えから外れて、回復不能としているのだがリードタイムアウトであろうと再試行するようなプログラムではpanicを考慮しなければならない。
一方でTcpStreamの多くはResult<>を返すので、高度なプロトコルを作るような場合、受け取ったデータなどを調べてpanicさせる方法などが公式ドキュメントにも述べられている。

120 名前:デフォルトの名無しさん [2023/01/29(日) 21:46:28.34 ID:6XW+IoFB.net]
The Bookに書いてるようにpanicを使う対象となるような回復不可能なエラーは常にバグによるもの

Rust groups errors into two major categories: recoverable and unrecoverable errors.
Unrecoverable errors are always symptoms of bugs.



121 名前:デフォルトの名無しさん [2023/01/29(日) 21:56:31.01 ID:saQmfbkd.net]
>TcpStreamにはset_read_timeoutでタイムアウトを設定すると、それ設定値以上でpanicを起こす。
readで設定したtimeout値を超えたらpanicすると言ってる?
少なくともリファレンスにはResultが返されるとあるんだが

122 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 21:57:37.90 ID:K3YIwpIF.net]
>>113
_exitはexit_groupのラップ関数だよ

123 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 22:09:10.65 ID:+VDCQEdm.net]
言語の理想と実装は違うから食い違いが出ている。現実的には作者がめんどくさくなったり、ライブラリとそれを利用するレイヤーの区別があいまいな場合などに大域脱出とスタック巻き戻しがしたいだけで回復可能な場合にもpanicを投げてしまう実装もありうるのでバグではない。標準ライブラリでさえそうなのだから

124 名前:デフォルトの名無しさん [2023/01/29(日) 22:14:20.10 ID:jL8Axswy.net]
> 受け取ったデータなどを調べてpanicさせる方法などが公式ドキュメントにも述べられている。
これはpanicを使えということじゃなくサンプルコードとしての簡潔さ優先してるだけ
改善はされてきてるけどunwrapがあちこちにあるのと同じ
箸の上げ下げレベルで手取り足取り教えてもらうことを期待し過ぎじゃないか

125 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 22:21:53.21 ID:qSgQK/Ke.net]
>>118
うん別に良いデザインではないよ、そこは同意する
俺は「同じexitがあるのに」という表現が招きかねない誤解に釘を差しただけです

126 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 22:33:36.00 ID:+VDCQEdm.net]
>>124
もちろんドキュメントで述べられてる通り、Resultが一番の選択肢で回復可能で返せるのにpanicを使うのは愚策でしょう。だから理想はとそういってますよね?
手取り足取り教えてもらうのはどちらなのかというよりも、どうしてもpanicで終了はバグだという理想・意見をとゴリ押ししたいだけに見えます。
これは(=回復可能なのに)panicを使えということじゃなくというのは強く同意ですが、そうなっていないものを使用している現実があるという話でpanicを書いてないことに期待し過ぎじゃないか?ということになります

127 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 22:38:36.38 ID:yP5ym/xP.net]
>>119
Rustでそのような形のpanicの使われ方はしませんしpanicは起きません
タイムアウトもio::Resultでio::Errorが返るだけです

これはC言語で書いてSO_RCVTIMEOでタイムアウト値を設定してreadで-1とerrnoが返る時と全く同じ状況です
言語独自の例外機構を持つ言語は複雑にしてややこしくしているだけなのでその考えをまず捨てるところからスタートしましょう

128 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 22:44:10.80 ID:yP5ym/xP.net]
>>126
今回のケースでも標準ライブラリはpanicを起こしていませんしpanicを起こす仕様はありません
もしpanicが起きたのならばそれはあなたがResultの処理をせずに強引にunwrap()したためであり
あなたのコードがpanicを引き起こしたのです

129 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 22:49:39.52 ID:ZDOIjMr/.net]
The BookにmainまでResultで戻す実践的な設計方法って解説されてる?
機能の説明はあっても実装するうえでどのようにしたらいいのかってところは抜けているような
ググるとstd::num::*を返す例、Stringを返す例、enumを返す例などが出てくるが
どのように使い分ければいいのかって点は不明
このスレ見ていてもこの部分に関する資料を提示している人は見かけないし

>>124
>箸の上げ下げレベルで手取り足取り教えてもらうことを期待し過ぎじゃないか
箸文化圏なら要らないだろうがスプーン・フォーク文化圏なら要るんじゃね
他所と大きく違うのであれば十分な説明を求められるのは当然では

130 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 22:51:25.05 ID:CZoRokqJ.net]
> 例には、不正なデータを渡されたパーサとか、 訪問制限に引っかかったことを示唆するステータスを返す
> HTTPリクエストなどが挙げられます。 このような場合には、呼び出し側が問題の処理方法を決定できる
> ようにResultを返してこの悪い状態を委譲して、 失敗が予想される可能性であることを示唆するべきです。
> panic!を呼び出すことは、 これらのケースでは最善策ではないでしょう。



131 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 23:19:15.93 ID:B9jwmLl6.net]
>>129
mainまでResultで戻すにはResult型を返す関数を書くだけ
何も難しいことはなく複雑なこともなくシンプル
Resultは単なる型の一つでOk値とErr値のEnumに過ぎない
Rust言語はResultに対し例外機構のような特別扱いをしていない
ResultはTryをimplしてるから『?』オペレータを適用できるなどくらいしか他の型との違いはない
したがって新たに勉強すべき点はそこだけだが『?』は使わずとも同じことを記述することができる

132 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 23:31:48.93 ID:ZDOIjMr/.net]
>>131
Result<T, E>のEってなしに出来たっけ?自分が言いたいのはそういう話なんだけど

133 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 23:45:24.52 ID:B9jwmLl6.net]
>>132
特別扱いはないので自由
例えばbool相当としてResult<(),()>型を使ってももちろん機能する
またOption<T>相当としてResult<T,()>型
通常はそれぞれ前者を使って必要なところで初めてResultへ変換が普通

134 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 23:50:28.46 ID:X9CS5Y/7.net]
>>129
> The BookにmainまでResultで戻す実践的な設計方法って解説されてる?
12章はどうだろうか、minigrep を作るところ

135 名前:デフォルトの名無しさん [2023/01/29(日) 23:59:14.71 ID:/s+aPXiv.net]
>>129
12章に書いてるでしょ

それに一連のレスで書いてる設計指針はRust特有の話じゃないよ
アプリのトップレベルに集約エラーハンドラを用意するのは例外機構のある他の言語でも同じだし
エラー発生時にexitcodeを設定してプロセス終了させるのはUIに相当するレイヤーの仕事だからそこまで戻してハンドリングするのも他の言語でも同じ
pythonだとしてもいろんなレイヤーでsys.exitするのは典型的なダメなやり方

136 名前:デフォルトの名無しさん mailto:sage [2023/01/29(日) 23:59:23.38 ID:B9jwmLl6.net]
RustはResultを特別視しない
例えばGoのようにRustで(正常値, エラー値)とタプルで返す関数群でプログラミングしても同様に動く
じゃあなぜResultを用いるのか?
・統一した型があった方がいい
・二値ではなく二種のEnumでよい
・便利なメソッド群を標準で用意できる
・標準ライブラリをResultで統一できる

137 名前:デフォルトの名無しさん [2023/01/30(月) 00:00:50.47 ID:M6Z3pSeY.net]
すまん被ってた

138 名前:デフォルトの名無しさん [2023/01/30(月) 00:02:36.60 ID:RUd1b+83.net]
>>132
なんでEを無くしたいの?

139 名前:デフォルトの名無しさん [2023/01/30(月) 00:09:50.85 ID:Oa/BEQbJ.net]
Rust特有のエラーハンドリングの実践的な知識はanyhow/thiserrorの使い方を学ぶといい
それらのcrateを使わず自前でやるとしても何を用意する必要があるのかわかる

140 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 00:14:09.92 ID:q9Kf6jE6.net]
副作用がない関数なら大域脱出を使うべきでないのは分かる
副作用に寛容で大域脱出に不寛容なのは分からん



141 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 00:19:52.36 ID:1Kzq/YqA.net]
>>139
それは初心者には混乱の元
panicとか言ってる初心者たちが最初にすべきことは一つ
「unwrap()を使わずにプログラムを書く」

142 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 08:11:22.12 ID:sNrNLjHp.net]
>>109
>The process::exit function will stop the program immediately and return the number that was passed as the exit status code.
>This is similar to the panic!-based handling we used in Listing 12-8, but we no longer get all the extra output.
>・・・
>Great! This output is much friendlier for our users
exitの使用目的はpanicによる不必要なメッセージの抑制に読めるけど?>>112で触れられている副作用なんか完全スルー
それに明らかに大域脱出を意図した使い方
裏を返せばpanicのメッセージ出力が問題にならないのであればpanicでも構わないとも取れる

143 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 08:21:18.23 ID:e4IM4WvI.net]
もういいよ。お前はずっとpanic使っとけ。

144 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 08:28:01.11 ID:1Kzq/YqA.net]
Rustをきちんと学ぶ気があるならば
まずはpanicもunwrapも使わずにプログラムを自在に書けるようになること
そういう基礎ができていないから勘違いしてpanicにこだわろうとしてしまう

145 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 08:31:46.93 ID:uyNTp5VX.net]
評判の悪いthe book 日本語版にすら使い分けの記述あるのに、それを無視して回復不能なエラー処理以外でpanicを推奨しようとするのは何なのかね。

エラー処理
Rustには例外が存在しません。代わりに、回復可能なエラーにはResult<T, E>値があり、 プログラムが回復不能なエラーに遭遇した時には、実行を中止するpanic!マクロがあります。

146 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 08:40:51.18 ID:VdE13u+1.net]
the bookを一通りきちんと読んだならunwrapは極力使うべきではないものだと理解できるはずなんだけどな

147 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 11:00:50.02 ID:R3gVBmE3.net]
>>138
panicで大域脱出して構わない状況ならmainで必要な情報はreturnするか否かだけ
これはResultが保持しているのでEは不要

148 名前:デフォルトの名無しさん [2023/01/30(月) 11:23:44.77 ID:hiS6eSAP.net]
>>147
すまんけど全然わからない
TとEの両方がないとResultが存在できないと思うんだが

149 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 11:26:30.09 ID:q36OfC0i.net]
TとEを()にしたら実質ないなので

150 名前:デフォルトの名無しさん [2023/01/30(月) 11:36:33.64 ID:2ZbeByHM.net]
>>142
ちゃんと読もう
そして全体の文脈を理解しよう
https://doc.rust-lang.org/book/ch12-03-improving-error-handling-and-modularity.html#fixing-the-error-handling



151 名前:デフォルトの名無しさん [2023/01/30(月) 11:50:16.61 ID:xWvH9QlK.net]
>>149
Eをunit typeにすることをEをなしにすると言ってることは理解したが
>panicで大域脱出して構わない状況ならmainで必要な情報はreturnするか否かだけ
これは全然わからない

大域脱出したいからpanic使いたがってるという動機部分は理解した

152 名前:デフォルトの名無しさん [2023/01/30(月) 12:08:29.21 ID:xWvH9QlK.net]
exitcodeをちゃんと実装したい時は
process::exitのリファレンスに書いてるように
mainの戻り値にTerminationを実装した型を指定してprocess::exitは使わずmainから戻り値を返す方法が今は推奨

153 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 12:56:41.01 ID:WhTmZ0y4.net]
>>151
処理継続不能なら終了するしかないからね。panicで終了しようが、mainまで戻ってからreturnしようが大差ない

154 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 19:01:04.95 ID:uxYUj7Ri.net]
>>153
いやいや、深いところから脱出するのにResultだと途中の階層すべてで返さないとダメだからコーディングの手間が全然違うだろ

155 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 19:07:00.52 ID:6jXELBYF.net]
>>154
でもアンチpanic君?はその手間を正当化したいっぽいじゃん

156 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 19:15:25.77 ID:mQYOoXSo.net]
日曜プログラマーの作るソフトときちんと作るソフトで基準がズレてる感じ

157 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 19:23:44.43 ID:mT8msQLw.net]
そうやってすぐ人格の問題にする

158 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 19:39:30.35 ID:dHwZCroo.net]
>>154
実際にコーティングしてみれば手間はほぼないと分かる
・返り値型をResult<>で括る
・ライブラリも自作もResult返す関数を上位へスルーするなら「?」を後置
たったこれだけの話
もちろんその場で処理したいResultや情報を増やしたいResultは今回の話以前に元々処理しているはず

回復不能なエラーなんて滅多に起きず
ほとんどはその場か上位関数で何らかの対応処理するエラーなのだから
panicは滅多に必要としない

159 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 19:54:44.86 ID:kIeP1yzV.net]
mainまで戻るってことはmain肥大化と同義。積極的にmainを複雑化させるべきいう主張か
もちろんプログラミングの定石的には1関数にあれもこれも詰め込むのは悪手だよな
panicダメ言っている人は実用的なプログラムを書いたことがあるのだろうか

160 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 19:54:52.38 ID:uxYUj7Ri.net]
>>158
> たったこれだけの話
それを途中の階層全てでやらんとダメだろ
お前こそでかいプログラム組んだことないんじゃね?
そもそも途中の階層は自分が組んでるとは限らんし



161 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 20:06:49.02 ID:Lj/9/9R5.net]
デストラクタ内でexitを使ってはいけない
デストラクタ内で利用可能な関数の中でexitを使ってはいけない
すべての関数はexitを使ってはいけない

こういうことかな

162 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 20:18:26.31 ID:TH7lLy8N.net]
なんかめっちゃ盛り上がってて草

163 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 20:21:20.63 ID:J7344Opw.net]
そもそもPythonのsys.exitだって本当は100点満点の正解コードを目指すなら独自例外作れって話だし
その程度の雑さでいいならRustでも雑にpanicしたっていいじゃない
教科書的な話じゃなく、もっと実利的な問題が何かあるなら教えてくれよ

164 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 20:22:42.83 ID:1Kzq/YqA.net]
>>159
mainまで戻る必要はない
通常は必要なところでエラー処理をする

>>160
エラー処理するところまでの途中のみでResult通過
だから手間なんてない

165 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 20:23:54.74 ID:i/bC1p00.net]
Rustに例外付けなかったの失敗だったな

166 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 20:27:14.41 ID:9ScRXeeN.net]
深い再入階層からジャンプして戻って来れる便利な例外

167 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 20:31:02.00 ID:Lj/9/9R5.net]
>>165
デストラクタ内で例外を投げないのは成功

168 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 20:33:32.03 ID:uC26F0Aa.net]
>>164
> 通常は必要なところでエラー処理をする
それは回復可能なエラーの話だろ

> エラー処理するところまでの途中のみでResult通過
> だから手間なんてない

169 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 20:50:07.22 ID:1Kzq/YqA.net]
>>168
まともなプログラムならば回復可能か否かに関係なく各々のエラー処理をきちんと行う
そのエラー処理を最下位関数内の関数呼び出し毎に行うのではなく中位の関数である程度まとめて行う時にResult返しとそのスルーで集める
このような下位のエラー処理をまとめて行うことはRustに限らずどのプログラミング言語でも同じ

170 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 20:50:28.09 ID:uC26F0Aa.net]
>>164
途中で送信してしまった

> エラー処理するところまでの途中のみでResult通過
途中?
main まで帰る話はもういいのか?w



171 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 20:51:44.09 ID:uC26F0Aa.net]
>>169
回復不可能なのにどんなエラー処理するつもりなんだよw

172 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 20:58:27.94 ID:1Kzq/YqA.net]
>>170
mainまで戻したいかどうかはそのプログラムの自由であってRustとは何ら関係がない
これは例外のある言語でも同じ
例外catchする場所はそのプログラムの自由

173 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 21:06:59.40 ID:uC26F0Aa.net]
回復不可能とか言わなくなってて草

174 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 21:07:51.47 ID:dHwZCroo.net]
元々の回復不能な話はこれだけど

>>47
>> ネットワーク前提にしてる時に、panicになるのはバグではないよ?

おもちゃなプログラムを除くとそういう状態は回復不能と扱わなくて
回復不能はまず滅多に起きることではないよね
そのケースだとネットワークが使えないことを知らせて使えるようになるまでデータを維持して待つ
panicで終わらせてよいのはかなり限定された場合だけとなるよね

175 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 21:19:29.68 ID:mdZRdLQP.net]
回復不能連呼してる人が具体的にどんな状況でのエラーを想定してるのか説明しないのに建設的な議論になるわけがないな

176 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 21:38:32.03 ID:jfU7NhFo.net]
プログラムを使う側からしたら回復可能かどうかなんて些細な問題で処理できる or できないがすべて
そもそも技術的に回復可能であってもそのような実装になっていないプログラムなんて腐るほどある

177 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 21:42:16.22 ID:1Kzq/YqA.net]
>>173
既に書いたように回復可能か否かに関係なくエラー処理は行われる
そして上位でまとまった共通なエラー処理をする時に
途中関数での?オペレータ付加とResult返しのみでRustでは実現できる
例外機構という複雑で非効率な仕組みは必要ないという話が本題

178 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 22:02:40.15 ID:jfU7NhFo.net]
>>174
>そのケースだとネットワークが使えないことを知らせて使えるようになるまでデータを維持して待つ
それは対話式のUIを持っているアプリ限定。CLIのアプリならエラーメッセージを出力して終了するのが一般的

179 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 22:10:02.38 ID:1Kzq/YqA.net]
>>178
その場合でもライブラリの奥底からResult返しの連鎖があり
エラーメッセージを出力する上位まで来てからそのResult処理をする形に変わりなし
個別プログラムの方針とは関係ない共通の話がなされている

180 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 22:13:28.38 ID:IhW3z+yo.net]
コマンドラインオプションでリトライ指定機能追加するときに
なんでもかんでもpanicだと泣きを見るぞ



181 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 22:19:43.76 ID:uC26F0Aa.net]
回復不能って言ってるのにリトライ機能追加とかw

182 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 22:21:01.07 ID:uC26F0Aa.net]
>>177
だから実現はできるけど面倒だって話

183 名前:デフォルトの名無しさん [2023/01/30(月) 22:26:05.18 ID:N/PzAAZV.net]
fs::read_to_stringでエラーが返されたら回復不能なんでしょw

184 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 22:38:54.58 ID:IhW3z+yo.net]
>>181
接続失敗するだけでpanicにしてるらしいからな

185 名前:デフォルトの名無しさん [2023/01/30(月) 22:40:43.76 ID:xNQxd4Kt.net]
>>178
curlとかリトライできたりするCLI使ったことないの?
元の質問者が>>39でGUIへの対応方法がわからないと言ってるのも本質的なエラー処理を理解せずpanicしてるからだぞ

186 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 22:43:08.31 ID:jfU7NhFo.net]
>$ cat foo.txt
>cat: foo.txt: そのようなファイルやディレクトリはありません
ここで正しいファイル名を入力しろなどと言いだすCLIアプリは相当レア

187 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 22:48:41.78 ID:mdZRdLQP.net]
>>186
その状況でエラー出して終了させるのは良いとして、まさかpanicさせるなんて言わないよね?

188 名前:デフォルトの名無しさん [2023/01/30(月) 22:49:07.10 ID:Rt4q8oMT.net]
>>186
$ cat foo.txt bar.txt
とでもやってみろよ

189 名前:デフォルトの名無しさん [2023/01/30(月) 22:53:39.09 ID:xlgBAXsb.net]
「回復不能」って言葉がよくないんだろうな
エラーの種別についてある程度の前提知識を持ってないとなんでも恣意的に回復不能に分類しちゃう

190 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 22:59:07.16 ID:nWXKDIRj.net]
通りすがりのF#erですが、RustでもRailway指向ってオススメですか?



191 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 23:25:38.10 ID:nWXKDIRj.net]
F#の記事ですが、ResultかpanicするべきかをRailway指向を考えた方が記事にしてます。
https://fsharpforfunandprofit.com/posts/against-railway-oriented-programming/

ドメインエラーはResult、それ以外はpanicの方が良いって言ってるぽいかな。

192 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 23:30:11.69 ID:dHwZCroo.net]
>>183
その場合でも例えばこのように
Result処理せずにunwrap()してpanicさせたら困ることをpanic派が気付いているかどうかだよね

fn foo(path: impl AsRef<Path>) -> String {
 let text = fs::read_to_string(path).unwrap();
 // テキスト処理略
}

193 名前:デフォルトの名無しさん [2023/01/30(月) 23:56:32.97 ID:WvBRUZ9a.net]
>>191
それは例外を使うべきケースと戻り値でエラーの種類を表現すべきケースの区別を例外機構のある言語を前提に語ってるもの
エラーの種別についての前提知識としては役立つがRustのResultとpanicの区別とはまた違う

その人が3種類に分類したエラーのうちPanicsだけがRustで言うところのpanicを使うケースにあたる

194 名前:デフォルトの名無しさん mailto:sage [2023/01/30(月) 23:59:11.83 ID:dHwZCroo.net]
>>191
その文書のResultやpanicはもちろんRustのそれらとは意味が異なるよ
そして代わりに例外でエラーを返すと書かれていてもRustには例外は無いわけでw

195 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 00:14:04.93 ID:c7ed+PvI.net]
複おじ死んだんじゃなかったの?
いい加減コテつけてくれよな
あと新年の挨拶もまだだろ?まだ1月のうちにやっとけ

196 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 01:21:48.37 ID:CDUXqGTR.net]
>>194
>>193
Rustは例外が無い>try-catchやthrowが無い。
という理解で有ってます?

となると、Resultの守備範囲が広くなりそうですね。

197 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 04:50:14.13 ID:JnYo5yDi.net]
panic・回復不能エラーは滅多にない。
Ruby on Rails でも滅多にない

ファイルが存在しない、数値に変換できないなど、予測可能なエラーは例外。
こういうのは普通に起きるエラー

たぶん、panicを使う香具師は、書き捨てのコードだろ。
リソースの解放・後始末が面倒くさいから

198 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 06:55:08.97 ID:YNMDboNb.net]
>>191
これに尽きるでしょ
・Panics.
These are errors that leave the system in an unknown state, such as unhandleable system errors (e.g. “out of memory”) or errors caused by programmer oversight (e.g. “divide by zero,” “null reference”).
要はpanicはプログラマーにはどうしようもないメモリー不足とかプログラマーの想定外の状態になったときに使うものだよ
他のプログラム言語でもAssertとか使うだろ

199 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 07:40:09.15 ID:7I30yv0f.net]
>>196
そう
Rustはtry throw catchの例外機構を意図的に排除している
例外機構の導入は複雑になるだけだなく効率面での不利や他の機能との相性など様々な問題がある
そのためRustやGoなどのプログラミング言語では例外機構が導入されていない

例外機構のある言語の多くでは例外が素通りする途中の関数でその宣言をしないためコードを見てもその有無が分からない問題もあった
Rustでは戻り型のResultによりそれを扱うことの有無が明確になっている
さらに"?"オペレーターによりResult値が下から上へ素通りすることも明確になっている

つまり簡素化と効率化と可読性の向上全ての両立をRustは実現している

200 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 07:49:11.46 ID:YNMDboNb.net]
>>199
> 例外機構のある言語の多くでは例外が素通りする途中の関数でその宣言をしないためコードを見てもその有無が分からない問題もあった
そりゃ途中の関数にはその例外は関係ないからね
関係ないものを見る必要はない



201 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 07:53:28.80 ID:7I30yv0f.net]
>>200
コードレビューやリファクタリングや移植作業をしたことがあればそれがコードに見えないことは非常に困ると分かる
Rustはそれがはっきりと分かるため可読性が良い

202 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 07:59:50.04 ID:Tm4r8coX.net]
mainからリターンするのであればプログラムの終了に至る条件が増えるほどmainの条件分岐がでかくなる
ってことも理解できない人がpanicダメとか言っているんだね

203 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 08:27:46.22 ID:cn1TJfcU.net]
このスレ見ていると、Rust勉強しているのにコールスタックとかスタックフレームを理解していないやつて意外と多いのが分かるな。

そもそもmainはスタックの根元で、OSとかプログラマーから見てプログラムそのものの代表だろ。
正常なフローならmainで始まってmainで終わるのは定石であって、正常なフローを破壊するpanicは異常事態。

Rustはスタックを重視してResultとか?演算子とか整備しているんだから、わざわざ用途外でpanicを使うのはRustのコンセプトを理解できていない証拠。そんなにスタックフレームのフロー制御が嫌ならRust以外を使ったら?

204 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 08:35:12.13 ID:7I30yv0f.net]
>>202
そもそもpanicするのはメモリ不足くらいしかない
それも最近はtry_reserve()などpanicを避ける対応も増えてきたがまだpush_within_capacity()など安定化していないな
あと固定サイズ内でやりくりするArrayVecのtry_push()を使うこともよくある

205 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 08:36:17.38 ID:mKWzzzcA.net]
例外がないせいで、複数ライブラリ使うとエラー型を合成する必要があってつらいわ

206 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 08:39:39.26 ID:08CfuspX.net]
>>200
入れ子になった関数の途中かどうかなんて関係なく、自身が呼び出した関数から出る例外に無関係な状況など考えにくいんだが

207 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 08:41:05.82 ID:YNMDboNb.net]
>>201
何が困るのか具体的に書いてみ

208 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 08:42:54.02 ID:YNMDboNb.net]
>>206
自分が関与しない例外なんだろ?
その関数にできることなんてないはずだが?

209 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 08:43:45.56 ID:7I30yv0f.net]
>>205
それは"?"オペレータのところでFrom::from(err)変換が自動適用されるので変換をimplしておけばよいだけ

210 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 08:49:38.58 ID:3fV3plkN.net]
panic派の主張は「肥大化するとなんかダサいからエラー処理サボってpanicさせとくわ。コード量は減ってスッキリするから格好いいでしょ」という風にしか聞こえない
どれだけ肥大化しようとも想定が必要なエラー処理を省略しては駄目だろう



211 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 08:49:41.53 ID:7I30yv0f.net]
>>207
例外がそこを通過するのか否かそこを見ただけで分からないからレビューでもリファクタリングでも何でも不便すぎる
一方でRustはそこがはっきりしていて可読性が良い
未処理な事項があって上位へ処理を委託していると明確に分かる

212 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 08:51:55.45 ID:LXCt1d5H.net]
>>205
とりあえず合成したいならanyhow使えばいい
勝手に全部合成されるから使い勝手は例外と変わらんと思うよ

213 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 09:03:32.22 ID:cRk5v+aU.net]
>>212
anyhowで勝手に合成されたエラー型への参照をmain()のifで場合分けしようとしたけど
JSのinstanceof 演算子的な処理のやり方が分からんかったわ

214 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 09:09:12.08 ID:YNMDboNb.net]
>>211
だから不便すぎるとかふわふわした言葉で語るなよw
具体的に何が不便なんだよ

215 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 09:12:07.56 ID:YNMDboNb.net]
>>210
panicはバグとかメモリー不足とかでどうしようない状態になったときに呼び出されるもので通常のエラー処理なんてできないってことぐらい理解しなよ

216 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 09:18:10.08 ID:7I30yv0f.net]
>>213
そういう使い方をしたいならば例えばライブラリA,B,Cに対してMyErrorをEnumでErrorA,ErrorB,ErrorC各収容した方が扱いやすさも効率も良い
そのEnumに格納するだけのコードimpl From<MyError> for ErrorAしておくだけで簡単

217 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 09:23:20.28 ID:cRk5v+aU.net]
>>216
全部自動でやってよ

218 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 09:28:45.86 ID:7I30yv0f.net]
>>214
Rustでは通過する途中の関数においても"?"オペレータの有無で未処理エラーを上位へ委託しているか否かが明白に分かる
だからコードレビューがしやすいし機能追加やリファクタリングする時にも見落としがない

一方で例外機構のある多くの言語では通過する途中の関数を見ても例外が通過するのか否かすら分からない
範囲を大きく広げて探し回らないといけなくなりムダな作業も発生して不便である

219 名前:デフォルトの名無しさん [2023/01/31(火) 10:14:19.93 ID:PU9Vswnw.net]
>>205
自分のcrate用にエラーenumを定義して下位のエラーはそれにwrapするんだよ
その辺を楽させてくれるのがthiserror

カスタムな例外を定義しなくてもBulit-inの例外を使い回すだけで規模の小さいプログラムなら書ける例外+継承のある言語とは違うところ
Rustの場合はioエラーのみとかじゃなければ常にエラーenumを書くようになる

220 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 10:15:37.08 ID:YNMDboNb.net]
>>218
だから自分が関与しない例外を調べて何をするんだ?
例外使うなら例外安全に作るのは当たり前でその関数が関与したリソースはその関数がきちんと始末することでなんの問題もないでしょ?



221 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 10:18:35.43 ID:7I30yv0f.net]
>>217
そこは自由度があるから自分で必要性に応じて仕様を決めるべき
完全にサボりたいならanyhow等を使えばよいがその代わりにdynによる非効率さと分類の扱いにくさがトレードオフ

222 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 10:29:38.37 ID:7I30yv0f.net]
>>220
中間関数は関与していないのではなくcatchしないことで例外エラーを上位へ移譲している
機能追加やリファクタリングではその処理位置が変わり得るから無関係ではなく把握する必要がある
同じことをRustならば上位への移譲があるか否かが明確に分かるため非常にやりやすい

223 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 10:37:25.48 ID:YNMDboNb.net]
>>222
> 機能追加やリファクタリングではその処理位置が変わり得るから無関係ではなく把握する必要がある
そりゃその関数が関与するような修正するならな、当たり前
でも全ての関数が毎回関与するわけじゃないだろ
なんかダメな理由を必死に探してるとしか思えないけど

224 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 10:41:06.15 ID:7I30yv0f.net]
>>223
コードレビューでも同じ
上位への移譲の有無がはっきり分かるRustは可読性が良い

225 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 11:26:55.99 ID:5zDIQfkR.net]
メモリ不足でパニックとか言っている時点で全く判かっていないの草
メモリのアロケーションに失敗した場合パニックしてもその動作は保証されない
なぜならスタックの巻き戻し中にメモリのアロケーションが試みられないことを保証するのは難しいからだ
そのアロケーションに失敗した場合に二重パニックになる
パニック時にアボートする場合は別だが、その場合はリソースやロックの開放もれが発生する可能性があるね

226 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 11:52:51.31 ID:df6faTWR.net]
>>225
全然ここの話を聞いてなかったけど、C++だとデストラクタは内部で例外を発生しては
ならないと決まっているから、デストラクタ内部ではメモリー不足例外も
発生させてはならない。

227 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 11:55:03.20 ID:df6faTWR.net]
>>226
[補足]
Java などでは、例外を投げるには throw new SomeException(); のようにするが、
C++ では、throw SomeException() のようにする。つまり、前者はヒープから、
後者はスタックから例外オブジェクトを確保する。なので、例外throwそれ自体は
メモリー不足にはならない。

228 名前:デフォルトの名無しさん [2023/01/31(火) 11:56:57.46 ID:eIPLUE+9.net]
Resultでエラーを表現する一番の目的は
抜け漏れなくエラー対応してることを
シグニチャーを見ただけでわかるようにして
簡単に静的チェックができるようにするため

229 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 12:41:27.68 ID:YNMDboNb.net]
>>224
いらない情報書かれても読みにくいだけ

230 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 12:44:13.13 ID:+FKSpugG.net]
今日もpanic警察が必死です。MISRA-C警察みたい



231 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 12:45:18.07 ID:YNMDboNb.net]
>>225
メモリー不足で動作が保証されないなんて常色だろ
同じくプログラマーの想定外の場合でも動作は保証できないからそういう時は余計なことしないで早期に終了させるしかない
panicってそのためのものだよ
なので個人的にはrustのスタック巻き戻しはやり過ぎだと思ってる

232 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 12:46:06.11 ID:YNMDboNb.net]
>>230
必要ないと思うなら使わなきゃいいのになぜか鬼の敵みたいになってるの草

233 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 12:47:09.57 ID:oegPHy5Y.net]
panic使う人は使っても困らないような
プログラム開発してるだけ
本人が困ってないならそっとしておけ

234 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 12:51:11.39 ID:CpP2rI02.net]
panicを使う理由が対応コード書くのがめんどくさいとか見通しとか回復可能でも呼ぶぜってところからきた話なので
回復不能エラーで呼び出された場合とか当たり前なところ話しても議論にもならんやろ

235 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 14:46:39.65 ID:YNMDboNb.net]
> 本人が困ってないならそっとしておけ
と言いながら構わずに居られない>>233であったw

236 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 15:00:44.42 ID:hwxs0+db.net]
病院行ったほうがいいよ

237 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 15:03:53.55 ID:ylr44mGO.net]
>>233
元からそういう話だぞ。panic原理主義者が発狂しているだけで

238 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 15:10:39.60 ID:3fV3plkN.net]
簡単にpanicされると困るようなプログラム作りたいからこそrust選んだのでは

239 名前:デフォルトの名無しさん [2023/01/31(火) 15:39:37.08 ID:CAp90nIJ.net]
JavaやC#あたりの経験もなくPythonやJavaScriptしか触ったことがない層がRustをやろうとしてるんだろうな
そうでもないと説明がつかない

240 名前:デフォルトの名無しさん [2023/01/31(火) 15:48:38.88 ID:BgaMS/KG.net]
言語というよりはエラー種別やドメインエラーをきちんと定義するようなアプリやシステムの開発経験がないからだと思われる



241 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 15:52:55.96 ID:+s4b9MNJ.net]
おじおじしてきたな

242 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 16:06:06.73 ID:YNMDboNb.net]
単発ワラワラw

243 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 16:33:36.83 ID:hwxs0+db.net]
自分以外がすべて同一人物が書いたかのように見えるなら病院に行きなさいって

244 名前:デフォルトの名無しさん [2023/01/31(火) 16:45:54.71 ID:VKWM6Cjq.net]
複オジ2世レベルやな
立場逆転してるのが感慨深い

245 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 16:51:02.90 ID:+s4b9MNJ.net]
そういえばこんなのもあったな
使ってやってくれ

Rustレスバトル会場
https://mevius.5ch.net/test/read.cgi/tech/1657382429/

246 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 17:01:16.78 ID:k74gCp3T.net]
レスバしたいだけにしか見えねえ

247 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 17:26:31.56 ID:5mHFhJcn.net]
GoとかRustとか例外サポートしなくなった言語、標準でスタックトレースサポートしなくなった辛さにみんなどう対応してるのかね。

エラーメッセージで grep とか、ログからコールスタックを想像とか、かなり辛いんですけど。

248 名前:デフォルトの名無しさん [2023/01/31(火) 17:30:47.95 ID:fFj0kljj.net]
スタックトレースサポートされてるぞ

だかスタックトレースないとどこでエラーが発生したかわからないような作りは見直すべき

249 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 18:11:46.10 ID:CpP2rI02.net]
古き良きline!マクロ

250 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 18:25:09.41 ID:Qz5B8C78.net]
c++勉強しているけどやっぱりrustっていいんだな
c++の場合どのオーバーロードが足りないかもエラーをチラ見しながら勘で判断するしかない
少なくとも能力の低いワイはそうやって対処している



251 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 19:05:37.94 ID:Tu8zoz2s.net]
例外連呼しているくせに具体的なことを書かない時点でエアプか煽りなんだろうな
例外機構を持つ処理系はエラー処理を局所化できるメリットがある
同様のメリットをRustで得るにはどのような実装が推奨されるんかな?

252 名前:デフォルトの名無しさん [2023/01/31(火) 19:31:24.49 ID:p+H/rvZ9.net]
そこまで言うなら見せてもらおうか。
スレッド間エラー転送とやらを。

253 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 19:36:37.66 ID:94wkFUZO.net]
https://i.imgur.com/f1bKLY1.png

254 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 19:41:28.43 ID:7I30yv0f.net]
>>229
Rustの利点に対して「いらない情報」と言い張るのはまるでアンチのように悪意があるなあ
可読性の向上という開発効率でのメリットと実行効率のメリットさらにスレッドやコルーチン実装のタスクからも伝播させることができるRust方式は非常に優れているよ

255 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 19:47:33.31 ID:YNMDboNb.net]
>>254
だからその情報がなぜ必要なのかを書きなよ
毎回可読性の向上って念仏唱えられても困る

256 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 19:51:16.79 ID:7I30yv0f.net]
>>247
Rustは標準でスタックトレースをサポートとしている
何でもいいからコンパイルして実行したことあればRUST_BACKTRACE=1と環境変数をセットすれば出力すると表示されることすら知らないのは不思議
ちなみにstd::backtrace::Backtraceによって自由自在に好きなところでバックトレースをキャプチャすることも出来る

257 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 19:56:49.64 ID:7I30yv0f.net]
>>251
Rustでもエラー処理を上位に委託してエラー処理を一箇所に局所化できる点は全く同じ
いくら初心者でもネット上のBOOKやサンプルや書籍など見てコードを書けばすぐに分かること

258 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 19:58:31.81 ID:iWzBLVlH.net]
>>255
254じゃないけど、メリットは分かりやすいけどなぁ。
関数のインターフェイスに、関数の作用に関する情報がまとまっていたらそりゃ便利だろう。

例外を投げる関数の場合、例外に関する情報は関数のマニュアルを参照するかソースを参照するしかないことがほとんどじゃない?インターフェイスを見ただけで例外を把握できる言語てあったっけ?

259 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 20:06:28.07 ID:0vRdrBrN.net]
ML系の系譜の言語はまあ大体そうなんじゃね

そしてRustでもdyn Errorで返されたら結局同じことやらされる羽目に……

260 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 20:17:47.02 ID:YNMDboNb.net]
>>258
だから例外に関与しないのになぜそんな情報いるんだ?



261 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 20:25:27.93 ID:QTaicIN8.net]
>>260
マジでそれ言ってるの? マジで?

例外を無視しても「例外が投げられる」という作用は消えないよ?
例外が投げられても「俺関与しないから」と言って無視するの?

262 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 20:27:00.46 ID:1QZESm3t.net]
例外に関与しないってどういう意味なんだろう?
ガン無視するって言ってるんだろうか?

263 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 20:36:05.54 ID:YNMDboNb.net]
>>261-262
いちいち曲解するなよ
下位で発生した例外は何もしなければそのまま上位に伝搬するだろ
例外安全に作られてればその関数で確保したリソースはちゃんと解放される
それは下位の例外の種類に依存しない

264 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 21:10:03.87 ID:QTaicIN8.net]
>>263
「上位に伝達する」という意味わかっている?
>258がインターフェイスの話をしているのは理解できている?

関数の呼び出し元からすれば、呼び出し先で投げられているのか、さらにその先で投げられているのか、とか関係なく「関数を使ったら例外を投げられた」だよ。関数のユーザーからすれば「投げる例外くらい明確化するのが常識だろ」と思うよな。

関数が例外を投げるのに、その関数の作者が「例外に関与しないからオレ知らね」とか言って逃げたらブチ切れるわ。そんなんだったら例外全部catchして関数の外に漏らすな、と。

265 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 21:16:22.90 ID:1QZESm3t.net]
>>263
例外安全って意味広すぎて
強い保証したいときとかあるやろ

266 名前:デフォルトの名無しさん [2023/01/31(火) 21:28:25.11 ID:Qz/Q1rYV.net]
Javaの検査/非検査例外以降の約20年余りの試行錯誤の結果辿り着いた現時点でのベストプラクティスを採用したのがRustやSwiftのエラー処理モデル

C → Java → C# → Go →Swift/Rust

267 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 21:35:24.95 ID:Mxurit6u.net]
>>263
そうやって
ヌルポで落ちるプログラムを量産したんだよね

268 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 21:42:42.48 ID:QTaicIN8.net]
まぁ、Result使うとしてもtry catch finallyブロックみたいなフローが欲しいというのはわからんでもない。

関数から抜ける時にResultを漏らさず処理したいというのはたまにあるし。

269 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 21:48:12.48 ID:jD2BQUnk.net]
>>263
catchとかしないの?回復処理したり付加情報付きの例外投げ直したり
そのためにはcatchすべき例外が上がってくるかどうか知らないといけないんだけど

270 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 22:04:35.47 ID:WaCEL3Yw.net]
この件でプログラミング言語が最低限サポートして欲しい点2つ

ある関数(ライブラリ)を使おうとした時に
①その関数やその子孫からエラーや例外が上がってくるのか、それとも全て処理済なのか?
これが奥深く辿らなくても局所的に把握できること
ドキュメントベースはそのミスや見落としが生じるため不可
②エラーや例外が下から上がってくる関数を用いた時に、
その処理をせずに続行してしまうコードを書いてしまったら、実行前に言語システムにより防げること

例えばRustならば①は返値がResult型かどうかですぐに把握できる
②は型システムによりRustコンパイラが型不一致や未処理放置Resultの存在を伝えてくれる
Rustは現在ベストなプログラミング言語と言い切っても過言ではない



271 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 22:16:44.29 ID:Mxurit6u.net]
>>270
高い信頼性が要求されないプログラムなら
例外と集約エラーハンドラさえあればいいんだから
Rust的なモデルが最適化どうかは要件次第だよ
結局はトレードオフ

272 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 22:19:53.43 ID:Mxurit6u.net]
>>268
今でもResultを漏らさず処理できると思うんだけど
できないのってどういう状況?

273 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 22:45:41.29 ID:WaCEL3Yw.net]
>>271
趣味のおもちゃプログラムでなければ信頼性は必須だよね
それだけでなく>>270の最低限の2点はプログラマーにとっても必要なこと
①を満たせない言語では無駄に調べまくらなければいけない
②を満たせない言語では無駄に実行時デバッグを強いられる
トレードオフと言われても信頼性と開発効率を両方落とすのは割に合わない

274 名前:デフォルトの名無しさん [2023/01/31(火) 23:47:23.84 ID:ovWek0QN.net]
使いたい関数だけじゃなくて、その関数が使ってる関数、更にその関数が、、、って調べていかないといけないのが無駄にコスト高になるんだよね。

275 名前:デフォルトの名無しさん mailto:sage [2023/01/31(火) 23:54:22.59 ID:hwxs0+db.net]
>>274
使いたい関数のシグニチャ見れば分かることだろ?????

276 名前:デフォルトの名無しさん [2023/02/01(水) 00:33:02.66 ID:CK4ZTpUy.net]
やっぱ複オジは成長しねーな
2世と同類だわ

277 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 03:40:06.80 ID:RyGmTTdX.net]
>>275
それが正しいか信頼できんだろ

278 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 06:17:22.82 ID:5NtLPUR3.net]
>>275
Rustならば使う関数のシグネチャを見ればResultが返ることで>>270の①を知ることができるけど
例外機構の言語の多くはシグネチャには情報がないため完全に信頼できるドキュメントでもない限り下流の関数全調査になるかな
②の処理忘れ防止機能も含めてRustが最も整備されている言語という感じ

279 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 07:12:22.77 ID:Hf88nfPH.net]
>>264
だから上がってくる例外を処理する必要があるならその時に調べればいいでしょ?
例えばprintfみたいな関数作ってる時に下位のputsみたいな関数がI/Oエラーで例外上げてくるだろうけどそれはそのまま上位にあげるだけだろ
いちいち意識する必要はない

>>265
強い保証の意味がよくわからんが自前でキャッチして処理すれば良くね?

>>269
全ての関数で回復処理が必要なわけじゃないし情報を付加するだけなら例外の種類を問わずにキャッチしてスローすればいいでしょ
すべての階層で事細かく例外をキャッチしてスローし直すなんてことは普通やらないよ

280 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 07:21:02.47 ID:Hf88nfPH.net]
>>270
言いたいことはわかるけどそれを実現する手間が掛かりすぎると思う
そもそも例外を上げるかどうかだけを見たいならnoexceptを真面目に実装すればいいだけだし



281 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 08:02:53.27 ID:5NtLPUR3.net]
>>280
それを実現する手間が掛かりすぎる、という視点がむしろ既に間違えているのかもね
従来の例外の枠組みを持たずにRustは>>270の二点をシンプルで効率よく実現してしまった
つまり従来の例外の枠組みよりも利便性と信頼性の高い新たな枠組みが実用的だと示されたのだから
従来の例外の枠組みを捨てるべき時が訪れたと解釈する方が正しいのかもしれない

282 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 08:17:31.54 ID:rokbXrwB.net]
>>272
あ、漏らさず処理はできるな。ごめん。

言いたいのは「似たようなエラーをまとめておいて、修正も一括で行う」のイメージだった。
例えば「関数内で細切れでファイルに書き込んでいるとき、どこかで書き込みエラーが出たらロールバックしてログを取って再書き込みする」とか。

>>279
やっぱり全然理解できていないな。
その「printfみたいな関数」を使う「上位」のプログラマーはどうすんだよ。「例外に関与しないからオレ知らね」か?
そんなんだったら例外全部catchして関数の外に漏らすな。

283 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 08:17:38.20 ID:Hf88nfPH.net]
>>281
> 従来の例外の枠組みを持たずにRustは>>270の二点をシンプルで効率よく実現してしまった
シンプルだけど生産効率は良くないよね?
って言ってるんだけど...

284 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 08:20:02.84 ID:Hf88nfPH.net]
>>282
上位で処理する必要があるならその時に調べればいいだろ
途中の関数で逐一調べる必要はない
そもそも最下位の関数に新しいエラーが定義されたらrust使いは全部調べ直すのか?

285 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 08:25:05.41 ID:ATJMUMOg.net]
>>279
その調べるかどうかをどう判断するかって話なんだが…
putsがI/Oエラーを上げてくるって知ってるから無視して上に上げるって判断ができるわけ
じゃあライブラリXの関数Yは無視すべきなのかそうでないのか?ってこと

286 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 08:27:52.62 ID:rokbXrwB.net]
>>284
どうやって調べるのか、具体的に考えた?
インターフェイスしか提供されていなくて、ソースコードの無いライブラリとかでどうやって調べるの?

エスパーか神様でもなければ不可能だね。

287 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 08:30:01.09 ID:5NtLPUR3.net]
>>283
むしろ>>270の二点をサポートしているRustは開発効率が高いでしょう
それらをサポート出来ていない従来のプログラミング言語は開発効率も信頼性も低いわけです
開発効率と実行効率と信頼性の高さを両立させたRustの地位は揺るぎないと思われます

288 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 08:37:05.02 ID:rokbXrwB.net]
ダックタイプ系の開発効率を求めるならRustは選択すべきじゃないよね。メモリの取り扱い見ればRustは「作法を強制する言語」だということは明らか。
そういうのはPythonとかRubyとかスクリプト言語があるんだからそっちを選ぶべき。

289 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 08:41:21.89 ID:wznv5J1H.net]
>> 279
> 強い保証の意味がよくわからんが自前でキャッチして処理すれば良くね?
他は既に突っ込まれてるから言わんが
例外に関するプログラミングしてたらすぐにわかる概念だからググれ
つうか例外安全って言葉使うなら知っとけ

290 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 08:54:40.02 ID:Hf88nfPH.net]
>>285
例えばprintfみたいな関数で下位の例外を処理するのか?
処理するとして何をやるんだ?
って話
考え方が逆なの、自分に関与しない例外は触らない

>>286
ライブラリならドキュメントに書いてあるでしょ

>>287
また呪文唱え始めたのかw
せめてこれに答えてよ
> そもそも最下位の関数に新しいエラーが定義されたらrust使いは全部調べ直すのか?



291 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 08:55:45.56 ID:Hf88nfPH.net]
>>289
> 例外に関するプログラミングしてたらすぐにわかる概念だからググれ
また無能のググれかよw
答えられないなら無駄に絡んでくるなよ

292 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 08:58:06.40 ID:ATJMUMOg.net]
>>290
別に調べ直す必要はないよ
下位にエラーが追加されても直接呼び出す関数のシグネチャが変わらないなら対応不要、変わったら対応するってだけ
結局呼び出す関数のResult型が対応すべきもののすべてなんだからそれ以外見る必要がない

293 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 09:02:33.17 ID:JRuvbVor.net]
>>288
そういうCPUもメモリも浪費するエコでない言語との比較はほとんど意味がないんじゃないかな
GC言語であってもそこそこ速いJavaやGoくらいの立ち位置の言語ならば比較の意味があるとしても

294 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 09:20:03.74 ID:JRuvbVor.net]
>>290
> そもそも最下位の関数に新しいエラーが定義されたらrust使いは全部調べ直すのか?

Rustでそんなことをする必要がないよ
元々他のエラーも返す関数だったならば返り値型が元々Result型だから枠組みは変化なし
新たにエラーを返すように返り値型が変わったならばコンパイルエラーで気付く

295 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 09:26:13.19 ID:ypE1x0h9.net]
fishシェルをRustで書き直すことが(ほぼ)決まったよ
https://github.com/fish-shell/fish-shell/pull/9512

C++ と CMakeをかなり腐してるけど意外に荒れてない
ちなみに提案者は開発リーダーなのでほぼ決まりでしょう
リンクされてる移行プランは他のプロジェクトでも参考になりそう

296 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 12:36:36.73 ID:o2DBVRIO.net]
>>292,294
> 元々他のエラーも返す関数だったならば返り値型が元々Result型だから枠組みは変化なし
なら、その新しいエラー(例えばディスクフルを検出してたが今回ディスクオフラインなんてエラーが追加された)の処理が抜けてないことはどうやってわかるんだ?
実行時にしかわからないなら例外と変わらん
むしろ途中の伝搬コードをいちいち書くのが面倒なだけだろ

297 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 12:42:13.45 ID:BH4poKX+.net]
Elixir にも、try/rescue の例外があるけど、あまり使わない。
throw/catch, raise でも、例外の発生場所を関数の外側から内側へ移すだけ

try do
%{a: a} = map
{:ok, a}

rescue
MatchError -> {:error, ":a が無い"}
end

とは書かずに、パターンマッチで書くのがElixir流

case map do
%{a: a} -> {:ok, a}
_ -> {:error, ":a が無い"}
end

298 名前:297 mailto:sage [2023/02/01(水) 12:45:24.97 ID:BH4poKX+.net]
>>297
修正。内側・外側が逆だった

>throw/catch, raise でも、例外の発生場所を関数の外側から内側へ移すだけ
throw/catch, raise でも、例外の発生場所を関数の内側から外側へ移すだけ

299 名前:デフォルトの名無しさん [2023/02/01(水) 14:01:39.16 ID:TUW+NsdV.net]
>>296
それはResult<T,E>のEで返されるエラーenumのvariantが増えるだけ
んでvariantが増えればEをハンドルしてるところでexhaustiveに処理してなければコンパイルエラー

300 名前:デフォルトの名無しさん [2023/02/01(水) 14:08:16.76 ID:w5pt5x/h.net]
>>282
>言いたいのは「似たようなエラーをまとめておいて、修正も一括で行う」のイメージだった。
これはResultのコレクションを返せばいい
例外のある言語でもこのケースは例外じゃなくエラー情報を貯めたオブジェクトを戻り値で返してエラーがあったかどうかをチェックして分岐するコードを書く
それと似たようなもの

>例えば「関数内で細切れでファイルに書き込んでいるとき、どこかで書き込みエラーが出たらロールバックしてログを取って再書き込みする」とか。
ロールバックする系の処理ならエラーを貯めずにエラーが一つ出た時点で中断するように作ったほうがいい



301 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 15:31:55.23 ID:4CkJdapD.net]
脳死でdyn Error突っ込んでるやつです

302 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 15:34:50.34 ID:ypE1x0h9.net]
dyn Errorで受け取った後の活用法が分からん

303 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 17:49:22.59 ID:HDxpsRMp.net]
dyn Errorでできるのは

・print!とかwrite!でログ出力する
(ErrorトレイトにDebugとDisplayが内包されてるからちゃんと実装されてれば何か教えてくれる)

・source()で内部のdyn Errorを掘り起こす
(エラーの原因のエラーがあれば一緒にログ出力できる)

くらいだからログ出力以上の活用がしたいならそのためのError型を使わないといけない

304 名前:デフォルトの名無しさん [2023/02/01(水) 18:15:38.74 ID:pHJayYFi.net]
>>302
具体的なエラーの型で分岐させたいならダウンキャストが必要(The Bookにも書いてたはず)
エラーenumを定義してwrapしたものに変換(map_err)しておけばダウンキャストは不要
anyhowに組み合わせてthiserrorの#[from]や#[error(transparent)]を使うと楽にwrapできる

anyhow/thiserrorのやってることに最初から自力で辿り着くのは大変だから先に使ってみて必要な要素を学んだ方が早いよ

305 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 19:06:46.56 ID:JRuvbVor.net]
>>303
dynはErrorに限らず自由に元へ戻せるよ
例えばstd::io::Errorを含むdyn Errorが返ってきた時

if let Some(io_err) = dyn_err.downcast_ref::<io::Error>() {
 match io_err.kind() {
  io::ErrorKind::NotFound => {

このように細かいエラーハンドリングが可能

>>304
順序が逆だよ
まずは標準ライブラリ内で上記のようにdyn Errorを使ったり
あるいはdynを使わずにimpl From<MyError> for io::ErrorでMyErrorのEnumに格納する「?」時の自動変換を書いたり
それぞれ簡単で単純なパターンなのだから標準ライブラリで基礎を身に着けた上で自作や外部のライブラリを選ぶのがお勧め

306 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 19:07:10.38 ID:sE34HuOS.net]
>>290
例外をサポートしているような言語なら、投げる例外を関数のインターフェイスとしてドキュメントに記載する。
Rustなら>>292


>考え方が逆なの、自分に関与しない例外は触らない

>290が>285 >286を理解できない無能だということは理解できた。
c++とかでライブラリ関数からドキュメントに無い例外を投げられた経験が無いんだろうな。おめでたい。

307 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 19:18:58.38 ID:RjOpz7Dl.net]
単発無能認定おじさん

308 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 19:27:56.01 ID:JRuvbVor.net]
>> ライブラリならドキュメントに書いてあるでしょ

ドキュメントは言語システムの一部ではないため
ミスで現実のコードとドキュメントが食い違っていることもあれば
ドキュメントは正しくても利用者が見落としてしまうこともある
大規模な開発になればなるほどミスや見落としが紛れ込むことは避けられない
特にエラー処理が済んでいるか未だなのかは致命的になりかねない

一方でRustは言語システムの中で下位関数からエラーが上がってくるか処理済か分かる
さらにResultが未処理のままだとRustコンパイラが指摘してくれる
言語システムとして少なくともこれらの機能を持つ言語へと今後は移行していくべき流れ

309 名前:デフォルトの名無しさん [2023/02/01(水) 21:57:57.91 ID:qgBIsers.net]
>>305
>それぞれ簡単で単純なパターンなのだから
実装の簡単さやパターンの単純さが問題じゃないんだよ
Rustのエラー処理に必要な「それぞれ簡単で単純なパターン」を網羅的に知識として仕入れてRustのエラー処理はこうやってやるものだと自信を持って言えるようになるまでの学習効率の問題
anyhow/thiserrorはそのパターンを楽に使えるよう作られてるから「ああRustのエラー処理ってこうやればいいんだな」ってのが標準ライブラリ前提で学ぶより断然早く理解できる

310 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 22:05:04.46 ID:JRuvbVor.net]
>>309
dynの取り扱いと「?」オペレータによる自動変換はRustの基本事項で必須の知識
もちろん標準ライブラリの中で完結して使えるしシンプル仕組みなのですぐ使えるようになる
この基本を習得せずに外部ライブラリへ行くことを勧めるのは基本知識を欠いた人を生み出してしまう愚かな行為



311 名前:デフォルトの名無しさん [2023/02/01(水) 22:25:39.32 ID:JqtaL/Do.net]
>>310
もしかしてパターンってdyn Errorと?オペレータ使った自動変換の話だけなの?
それだけじゃRustで現実的にどうエラー処理を実装すべきかThe Book読み終えたくらいの人にはわかんないと思うよ

312 名前:デフォルトの名無しさん mailto:sage [2023/02/01(水) 22:59:41.62 ID:JRuvbVor.net]
>>311
エラー処理パターンは様々な方針があり
その前提知識としての共通の必須事項として今回のスレの流れで話が出て来ていたdynの取り扱いと?での自動変換の話を書いた

例えばあなたが出したanyhowはdyn Errorを扱う外部ライブラリの一種
anyhow::Errorから具体的な型を取り出すためには>>305で書いたdynの取り扱い知識が必須
この知識を知らないと細かいエラー分類が出来ずにエラー表示のみしか出来ない人になってしまう

もう一つあなたが出したthiserrorも?での自動変換を用いる外部ライブラリ(というかマクロ)の一種
>>305で示したFrom::from()による自動変換の基礎知識を欠いたままでは仕組みすら分からず魔法のように外部ライブラリを使うダメな人になってしまう
応用が効かないだけでなく利用していて何か問題にハマった時に基本知識がないと解決することもできない

313 名前:デフォルトの名無しさん [2023/02/02(木) 00:32:13.04 ID:y8eaHXgz.net]
>>312
設計やプラクティスとしてのパターンのことを言ってたんだが君は言語機能のことをパターンと呼んでるみたいで噛み合ってないよね

dyn Errorや?オペレータ使ってinto経由で変換されるような基本的な機能面の知識はThe Bookにも書かれてるレベルだし多少分からなくてもリファレンス読めばいいだけの話
でもそれだけの知識でRust初心者がエラー周りの実践的な設計をできるようにはならないでしょ

314 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 00:53:57.92 ID:tzaW+blt.net]
anyhow/thiserrorは最近出てきた新興ライブラリ
当然それまでは誰も使っていなかったわけで初心者がいきなり必須なものでもない
初心者にとっては複雑で機能過多で理解しにくいのでまずは標準ライブラリから始めたほうが良いかな

315 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 01:38:05.78 ID:JL6WsU2I.net]
対象年齢付きのおもちゃか何か?w
自分だけ勝手に縛ってろw

316 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 03:39:28.87 ID:S9qGtTXE.net]
Rustは「教官付き教習車」だよ。
cとかと違ってアホが膝を撃ち抜く自由は許さない。
それが嫌ならRust止めれば?

317 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 07:11:05.90 ID:02L2EQ2o.net]
Rustはコンパイラの防波堤の中で安全な自由があるけどそれはともかく
クセの強いanyhowをRustの基本より先に初心者に教えるのはあかんよ
たとえば、他人も使うライブラリ作成ではanyhowの使用を避ける、といった当たり前のことも
エラーに関する基本を知らないと陥ってしまう

318 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 07:31:00.57 ID:c3pJ+FwE.net]
>>316
rustの免許とりたいんですがおすすめの教習所はありますか?w

319 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 07:34:23.41 ID:/W20jYzd.net]
anyhowはもはや標準ライブラリでしょ

320 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 07:55:32.16 ID:Cx26n0QZ.net]
>>317
あれはクセというよりanyhowの致命的な欠陥だ
分かってる人は配慮して閉じた環境だけで使うけど稀に公開ライブラリにanyhow使っちゃう無知な人もいる
基礎知識はホント一番大事



321 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 08:05:47.28 ID:VrfwqxiC.net]
>>318
コンパイラ(教官)はひとつしか無いから選択肢は無いよ。

322 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 08:14:13.18 ID:eMZEpDOV.net]
コードを貼るわけでも実装例を示すわけでもない時点でシッタカだろ

323 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 09:11:33.63 ID:ICVq01Bq.net]
anyhow勧めてる人自身があんまり理解してないんだと思う

324 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 12:40:03.75 ID:8vdGQp5R.net]
複オジが使ったことないだけだろ
>>312も今調べてきました感満載じゃん
デファクトスタンダードになってるライブラリまで排除したらrustでは何もできんぞ

325 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 12:47:49.51 ID:YyXCj6j+.net]
オライリー本にも実戦ではanyhowとthiserrorを使えと書いてる

326 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 12:59:53.51 ID:c3pJ+FwE.net]
>>321
うまいこといいますね。お見事!

327 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 13:20:28.44 ID:C8PK02xw.net]
禁忌事項はライブラリを作って提供する時にanyhowを使ってしまうことだけだから
そこはanyhowを使わずにthiserrorを使えばヨシ

328 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 15:47:50.42 ID:HD9HoUeH.net]
別にanyhowをthiserrorに差し替えるのも大した手間じゃないしな
ライブラリで使っちゃってるなら変更PRでも出してやれば良い

329 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 23:07:11.98 ID:3wRXRcn7.net]
>>325
anyhowとthiserrorを使うなと言ってる人は誰もいなくて
・まず先にstd::error::Errorを覚えよう
・次に?変換とdynダウンキャストを覚えよう
・そしてanyhowとthiserrorへ進もう
という話でしょ
そうすればanyhowをライブラリで使うべきでない理由もわかるでしょうし

330 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 23:14:43.66 ID:3quZbai0.net]
Rustの世界でダウンキャストってなんかキモいな



331 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 23:37:26.35 ID:wswA48V7.net]
むしろRust基盤の一つ
downcastはエラー処理に限らずdyn Traitを元の型に戻すために必須
anyhowでも元のエラー型に戻すために必須

332 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 23:53:43.61 ID:86yN0Q3V.net]
ダウンキャストのソース見てみたら
やっぱりunsafeのかたまりだった

333 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 23:53:52.64 ID:QEJ+oT50.net]
ダウンキャストを知らないと
>>303のようにdyn Errorで出来ることはログ出力だけと思いこんでしまう

334 名前:デフォルトの名無しさん mailto:sage [2023/02/02(木) 23:59:01.23 ID:Cx26n0QZ.net]
>>332
当たり前
Rustの標準ライブラリはunsafeだらけ
原理的にunsafeは避けられないからそれを安全なインターフェイスとして公開するのがRustの標準ライブラリ

335 名前:デフォルトの名無しさん mailto:sage [2023/02/03(金) 00:57:17.44 ID:teLYlQt8.net]
dynを元の型に戻すという発想に違和感(気持ち悪さ)を感じる人もいると思う
元の型に戻すつもりならそもそもdynにしないというか
ダウンキャストは戻すべき型(の変更)を全部把握できる閉じた状況じゃないと使いにくい

336 名前:デフォルトの名無しさん mailto:sage [2023/02/03(金) 01:37:41.39 ID:VgIBWdEw.net]
>>335
anyhowを使うのはそういう全部把握できる閉じた状況で
独自エラー型を用意するのが面倒な時に使うからダウンキャストが理に適っている
嫌ならanyhow使わずにthiserrorを使えばよい

337 名前:デフォルトの名無しさん mailto:sage [2023/02/03(金) 07:58:09.95 ID:+r7mcEDE.net]
>>335
型を全て把握しておく必要はない
例えばエラー処理で大半はエラー表示のみだが一部だけ特別な処理をしたいとすると
その処理したいエラー型のみダウンキャストして使えばいい

ちなみにダウンキャストは内部で定数のu64で表現される型番号をu64比較するだけなのでコストがかかるものではない

338 名前:デフォルトの名無しさん mailto:sage [2023/02/03(金) 08:54:57.66 ID:Vma9tJMI.net]
ダウンキャストの扱いかどうか知らんが、パターンマッチングも総和型から個別型ヘのキャストみたいなもんだろ。

339 名前:デフォルトの名無しさん mailto:sage [2023/02/03(金) 09:11:06.24 ID:+r7mcEDE.net]
もしdyn使わずに自作Enum収容エラー型を定義して使っても
Enumタグ比較で分岐することになるから状況は似たようなもの

340 名前:デフォルトの名無しさん mailto:sage [2023/02/03(金) 09:18:29.47 ID:H94wvEsC.net]
std::any::Any.downcast_ref() を使わずにanyhow独自に実装してるね



341 名前:デフォルトの名無しさん mailto:sage [2023/02/03(金) 09:36:29.67 ID:e19a6Rdo.net]
初めて間もないけど
println!("{}", a);
とか手が攣って辛い
tabでもprintlnまでしかでないしコピペでもしてるの?

342 名前:デフォルトの名無しさん mailto:sage [2023/02/03(金) 09:43:50.06 ID:90dUFc67.net]
downcastすればいいだけだからdyn Error返してもデメリットは無いってのなら
ライブラリでanyhowを使うのも大した問題じゃないって結論になるん?

343 名前:デフォルトの名無しさん mailto:sage [2023/02/03(金) 10:26:25.61 ID:5QmoSp+n.net]
>>342
anyhowの問題点はそこではない
anyhowは最も重要なことを実装していない(不可能)という欠点があるため

344 名前:デフォルトの名無しさん mailto:sage [2023/02/03(金) 10:31:15.17 ID:Vma9tJMI.net]
>>343
anyhowの問題点なんて一般的じゃないんだから、曖昧に言わずに具体的に説明しなよ。

345 名前:デフォルトの名無しさん mailto:sage [2023/02/03(金) 10:48:35.31 ID:yQvnFmTM.net]
予言しよう
ググれば分かるんだから書かないとか言って絶対に具体的な説明はしないやつだよ

346 名前:デフォルトの名無しさん mailto:sage [2023/02/03(金) 12:00:34.82 ID:7ZLHWUFf.net]
俺はなんも知らんから頭の片隅に覚えておくくらいにしとくわ
使うときに調べる

347 名前:デフォルトの名無しさん mailto:sage [2023/02/03(金) 12:23:43.68 ID:dwx7vokg.net]
>>345
検索しても出てこなかったよ。

348 名前:デフォルトの名無しさん mailto:sage [2023/02/03(金) 12:37:16.79 ID:tbHpIbwJ.net]
Rustでエラー型はstd::error::Errorトレイトを実装するのが共通のお約束だけど
anyhow::Errorは諸事情あって実装されていないんよ
std::error::Errorトレイト実装を前提として扱っているところへライブラリがanyhow::Errorを返しちゃうと困っちゃう
ライブラリを作るときはthiserrorでエラー型を作ればstd::error::Errorトレイトを自動で実装してくれるから大丈夫だよ
もちろんthiserror使わずに自分で実装してもいいよ

349 名前:デフォルトの名無しさん mailto:sage [2023/02/03(金) 15:29:10.83 ID:Vma9tJMI.net]
>>348
「このライブラリはanyhow対応必須です。anyhow対応しないと使えません」
ならOKかね。

350 名前:デフォルトの名無しさん mailto:sage [2023/02/03(金) 18:59:27.03 ID:NDb3ccU3.net]
Box<dyn Error>もErrorトレイト実装してないよ(コンフリクトで実装できない)
その点はdyn Errorで返してもanyhowで返しても大差ない
libraryのpublicなAPIでtype erasedなエラーを返したいときは
Errorを実装した独自のエラー型を用意するのが普通
anyhowで返してる有名ライブラリもあるけどね

ライブラリでanyhow使ったらダメなんてことは特にないんだけど
Readme読めばすぐわかるように基本的にはアプリケーション用

なぜ同じ作者のエラー系のライブラリがanyhowとthiserrorと2つあるんだろうか?
と疑問に持つだけでも初心者はstdベースで学習するよりも1歩先に進めてる



351 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 00:38:01.54 ID:5aCWsuCk.net]
ダウンキャストは静的チェックできず変更に弱いからホイホイ使うものじゃないよ

352 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 07:20:32.73 ID:eqpqpGi8.net]
>>351
ダウンキャストは静的に型を指定して
Some()で静的な型で値が返ってきて
その値の使用も静的に型チェックされる

「マッチングが動的ではないか?」については
Enumで複数の型を収容した場合と全く同じ
どちらの場合もマッチングは動的に行われるが静的に型チェックされる
どちらも静的に型を抽象化した定数の整数値との比較によるマッチングとなる点も同じ

353 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 09:46:17.84 ID:4OrKEijd.net]
ばかばかc

354 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 09:59:08.11 ID:wSUDs8sY.net]
Rustのdynとそのdowncastは安全性と最小限のコストを両立させており安心して使える
引数などでimpl Traitが使える場合はimplが有利なケースもあるが
返値などでdyn Traitしか使えない場合もあり適材適所で使い分け

355 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 10:30:58.71 ID:yB06Lfm4.net]
>>352
よくわかってないものを人に勧めちゃダメだよ

356 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 12:22:28.04 ID:eqpqpGi8.net]
久々に荒らし発生かな

357 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 12:44:13.93 ID:vEFKnpWX.net]
ダウンキャストの安全性みたいなのは downcast_ref 使ってりゃ議論の余地はないと思うけど網羅性は限界があるわね。

ライブラリはやっぱエラー型を明示すべき。

358 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 13:10:09.04 ID:QerlffZr.net]
match式によるパターンマッチでは、そのマッチアームによる条件網羅性がコンパイル時に検証される。
enumとmatch式は相性抜群だよな。
https://doc.rust-jp.rs/book-ja/ch06-02-match.html#%E3%83%9E%E3%83%83%E3%83%81%E3%81%AF%E5%8C%85%E6%8B%AC%E7%9A%84

359 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 13:39:49.84 ID:A1ugYU/e.net]
エラー処理で網羅性は関係ないだろ
std::io::Errorのenum ErrorKindからしてnon_exaustive指定だぞ
match式で網羅性はチェックされない
特別な処理が必要なエラーだけ処理対応して残りはエラー表示が普通だ

360 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 13:52:58.01 ID:RtFCJdnN.net]
エラー処理で重要なことは
・エラーが発生しているにも関わらずそのまま通常処理を進めないこと
・エラー表示以外の対応を必要とするエラーの場合にその対応をすること
・それ以外のエラーはエラー表示などをすること
enumタグレベルの網羅性を求められることはないな



361 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 14:46:52.23 ID:7PnUG+Eh.net]
元々の話はdyn Errorかanyhowか、だったような気がするけど、
anyhowはdyn Errorの自作ラッピングみたいなもので、
とちらを使ってもダウンキャストしなきゃいけない点も網羅性がない点も同じだよね。
そしてそれらをアプリ側で使ってる限り困ることもない。

362 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 17:06:34.73 ID:1vu2ZDPp.net]
そもそもがダックタイピングとか向いてる言語じゃない。
フロントでこの言語使おうとするとかただのバカでしかないわ。

363 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 17:36:37.29 ID:roDrLtFP.net]
唐突にフロントとかダックタイピングとかどうした?
しかもその二つも関連性がない

364 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 18:06:27.05 ID:uIknpDmG.net]
上位レイヤーも含めてエラーの内容によって分岐したいならdyn Errorはやめたほうがいい

365 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 18:34:38.01 ID:srvPtSil.net]
分岐にenumのタグを使うかErrorの型名を使うかの違いでしょ
enumを使うと一貫性を担保しやすいから保守性が向上するし
dyn Errorを使うとenumの定義を省略できるからコードを減らせる
自分は(分岐するなら)enum派だけど何を重視するかで結論が変わりそう
ただ「やることが一緒だからどっちも同じ」と考えはいただけない

366 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 18:40:15.09 ID:3y1LLse5.net]
>>364
dyn Errorをやめるべき理由がない
まさかと思うが代わりにanyhow使えとか言い出すんじゃないんだろうな?

367 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 19:00:20.00 ID:eqpqpGi8.net]
dyn Errorもダウンキャストも使用して全く問題ないよ
有名どころでも普通に使われている
例えばreqwestはdyn Errorを使っていてdowncast_ref()してエラー処理している
cargoはanyhowを使っていてdowncast_ref()してエラー処理している
使うのをやめたほうがいいと主張している人は一種の宗教にすぎないことに気付こう

368 名前:デフォルトの名無しさん mailto:sage [2023/02/04(土) 22:40:19.42 ID:JjHQagj1.net]
勘違いしてる内容が同じだから
自演しまくっても同一人物なの丸分かりだね
ダウンキャストオジ==複オジ

369 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 02:20:20.64 ID:VCqNNrEk.net]
無敵やな
もちろんいい意味で

370 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 02:25:01.54 ID:a/eU++XN.net]
一年ぐらい前にanyhowを標準化する、みたいな話なかったっけ?



371 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 02:59:04.83 ID:26rYdUrG.net]
anyhowはダウンキャストするしかないクソ

372 名前:デフォルトの名無しさん [2023/02/05(日) 06:00:11.27 ID:TqN0qcyT.net]
オライリーの本って出てから1年経つけどさあ
これの電子版って、セールになったりする機会ってあるもんなの?

373 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 06:31:13.67 ID:qzS4+JVd.net]
ダウンキャストを毛嫌いしてる人の心理を知りたい

374 名前:◆??? [2023/02/05(日) 12:21:29.64 ID:gCGZ2Fk+q BE:2843802656-2BP(0)]
std::mem::transmute

375 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 12:11:30.30 ID:vL4nY6Md.net]
>>359-360
おまえはまるで何もわかってないのな
エラーハンドリングの基礎すらおさえてないじゃん
無知なのはいいが自信満々で嘘を書きまくるのはやめろ

376 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 12:37:36.14 ID:yQ5U4c14.net]
作るシステムの性質や分野ごとで許されるエラーハンドリングは別物だからね。
ミッションクリティカルだけが正解ってわけでもないのよ。

377 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 14:02:09.96 ID:dIeXO9aa.net]
>>376
何がまちがってるかさえも分からないようならThe Bookを一から読み直して出直してこい

378 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 14:22:39.74 ID:Ib1Yzzhk.net]
たまに出てくる「間違っている」「勘違いしてる」「嘘を書くな」の人
今までも文句をつけるだけで正確を書いたことがないから信頼できないのよね

379 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 14:23:18.13 ID:8OOQa3AE.net]
どっちも自分の脳内シチュでしか語ってないからふわっふわで論破出来るわけもなし
自分の主張が通る具体例上げるといいよ

380 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 14:35:53.55 ID:LY0V54Tb.net]
「カッコウのアルゴリズムさえまともに実装できてないからクソ遅いんだよな」
みたいに適当なワード混ぜて意味不明なこと言いつつ同意してる風を装うと「そうなんだよ!」とか勝手に乗っかってきて自爆するから面白いぞ



381 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 15:42:56.66 ID:XUJKjP/6.net]
>>378
それは信頼以前に、相手にしなくていい外野

>>380
すごく目に見えるわその展開w

382 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 15:53:21.98 ID:ANWYibFj.net]
>>373
台所まで行けば箸(enum)があるのに手元のフォークで焼きそばを食べてる感じ
食べてるのがパスタ(Python)なら平気なんだけど

383 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 16:01:07.42 ID:3wawDpMD.net]
>>382
微妙にわかりにくい例えで草
でも複オジに比べると1000倍マシ

384 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 16:04:59.96 ID:0ZBI/vwq.net]
>>378
信頼するかどうかはあなた次第
>>359-360が嘘だらけだということが分からない人は基礎がなってないから勉強やり直すかパスタにするか

385 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 17:40:20.51 ID:X5wQdMGf.net]
網羅性が必要ないならResult使う必要もRustを使う必要もないわな

386 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 18:32:46.51 ID:rtbv+KUs.net]
>>382
凄い納得
enum使わずにanyhow使うような連中はPythonでも使っていろ
anyhowなんてものがあるから勘違いが起こる

387 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 20:10:29.95 ID:QsKcw+fO.net]
cargo crateのコード見てみた
anyhowを使ってエラーを上へ上げていく
enumを使っておらずエラーの網羅性はない
downcast_refを使ってエラー分岐している

388 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 20:38:51.85 ID:1L9Nz43N.net]
エラーなんて作成時点で未知のものが後から増えることもザラだし
何なら抽象レイヤー以下の実装の差し替え(ストレージのネットワーク化とか)で
動的に増えたりすることもあるんだから、網羅性とかすぐ成り立たなくなる。
可能なところで逃すものじゃないけど、こだわるものでもない。

389 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 21:15:55.10 ID:yQ5U4c14.net]
cargo みたいに手元や CI で実行するツールのエラー処理なんてその程度で十分ってこった。

もちろん、網羅が必要な領域のコードじゃそんなエラーハンドリングのやりかたじゃあ駄目だろうよ。

390 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 21:31:31.79 ID:kVul7/Hf.net]
多数の下部ライブラリから色んなエラーが上がってくるreqwestはそれらをdyn std::error::Errorへ入れているね
そしてdowncast_refで必要な分岐をして処理しているね
エラー処理はこれで十分でしょ
網羅しなくても残りは最終的にちゃんとエラー表示されるのだから



391 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 22:59:47.83 ID:cfofmdL5.net]
エラー処理で必須な網羅性とはenumの網羅性とは異なる
いつどこでどんなエラーが発生しても必ず処理されることがエラー処理の網羅性
つまりエラー処理されないまま通常処理に進まないことでありRustではResultの利用によりそれが保証されている
したがってdyn Errorを使って一部をダウンキャストによりエラー処理し残りをエラー表示処理でも網羅性を満たしている

392 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 23:51:35.27 ID:BjcIBdbF.net]
opaqueなerror typeを使うメリットは何なのか?デメリットは何なのか?
少なくともreqwestの開発者はそのトレードオフを検討した上で判断を下している

メリットもデメリットも理解できてないやつが珍説唱えても虚しいだけだぞ

393 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 23:54:47.07 ID:arvSMdBl.net]
>>391
おまえはエクストリームな言い訳並べ立てる前にnon_exhaustiveの意味から調べろな

394 名前:デフォルトの名無しさん mailto:sage [2023/02/05(日) 23:58:58.86 ID:QsKcw+fO.net]
>>391
やっぱりそれでいいのか
Rustの標準IOライブラリはenumを使っているけどnon_exhaustive指定がしてありenumの網羅性チェックをむしろ使えないようにしてる

395 名前:デフォルトの名無しさん mailto:sage [2023/02/06(月) 00:09:01.18 ID:ZXNgtENY.net]
>>391
一般的なエラー処理の網羅性はその解釈だな
Rustでは型システムと返り型Result及びResult放置をコンパイラが警告してくれるため必ず網羅される仕組み

396 名前:デフォルトの名無しさん mailto:sage [2023/02/06(月) 01:23:09.90 ID:Kt6dB8yb.net]
>>394
non_exhaustive指定があると
なぜenumの網羅性チェックが使えないの?

397 名前:デフォルトの名無しさん mailto:sage [2023/02/06(月) 06:52:59.94 ID:OJBoAdFu.net]
逆だよ
網羅性の扱いを禁止するために意図的にnon_exhaustive指定されている
そのようなエラーの種類には網羅性は必要がないだけでなく
今後もしエラーの種類が増えた場合に全網羅列挙して使用している既存のコードがエラーとなってしまう
そのためこういう時は不要である網羅性の扱いを禁止して全列挙コードを書かせないことで
今後エラーの種類が増えても既存の利用コードに影響を与えずに済む仕組み

398 名前:デフォルトの名無しさん mailto:sage [2023/02/06(月) 12:30:43.08 ID:wr+6RDlb.net]
>>397
自信満々に間違った情報を中身のない文章で膨らませてもっともらしく見せようとするところがChatGPTそっくりww

399 名前:デフォルトの名無しさん mailto:sage [2023/02/06(月) 12:48:04.84 ID:/nZ/7Knj.net]
昔ながらの例外論争見てるみたいだ
全部取ればいいいや個別だ

400 名前:デフォルトの名無しさん mailto:sage [2023/02/06(月) 14:14:21.50 ID:C/yeK4bx.net]
>>397で合っているけど補足すれば
全網羅列挙コードを書いてもコンパイラがそれを許さずエラーとなる
全網羅列挙しなくていいから必ず全マッチの _ => アームをコンパイラが要求してくる
つまりコンパイラによるエラーの網羅性チェックは不可能



401 名前:デフォルトの名無しさん mailto:sage [2023/02/06(月) 21:51:09.46 ID:MJNtWgHJ.net]
そもそもRust以前に他のプログラミング言語でもそのようなエラーの種類の網羅が行なわれたことはない
IOエラーだけでも何十種類もあり列挙するだけでも大変で意味のない作業
エラー処理で必要とされる網羅性とはエラーの種類を全て列挙することではなく
>>391の説明が正しい
RustでResultを使えば保証される

402 名前:デフォルトの名無しさん mailto:sage [2023/02/06(月) 21:59:33.19 ID:T23InEdz.net]
自分の書いたレスを正しい正しいと
一人で連呼してて虚しくならないのかな

403 名前:デフォルトの名無しさん mailto:sage [2023/02/06(月) 22:26:04.02 ID:7y0OcpN0.net]
エラー処理の網羅性という話は元々
関数からエラー値が返って来る可能性があるのに見落として処理せずに続行しちゃったり
あるいは例外が返って来る可能性があるのに見落として処理しないままでいたり
そういう見落としがよく起きていたから
いつどこでどんなエラー(or例外)が起きても処理漏れがないようにプログラミングしましょうという話

もちろんRustではResultで返せばコンパイル時点でエラーや警告が出るためエラー処理の網羅性は満たされます
Resultを返していればdyn Errorやanyhowを使っていてももちろん大丈夫
そしてエラー処理の分岐にそれらのダウンキャストを使うのも何ら問題なし

404 名前:デフォルトの名無しさん [2023/02/07(火) 02:02:21.05 ID:smEuFI89.net]
anyhow使ってて困ったことないので、これからもanyhow使いますね

405 名前:デフォルトの名無しさん mailto:sage [2023/02/07(火) 02:09:15.61 ID:2blGAjQQ.net]
enumで網羅派の完全敗北だな
anyhowやdyn Errorでdowncast_ref分岐して何ら困らない

406 名前:デフォルトの名無しさん mailto:sage [2023/02/07(火) 02:13:05.33 ID:fMWAnbF1.net]
anyhowは邪道だろ

407 名前:デフォルトの名無しさん mailto:sage [2023/02/07(火) 10:30:33.69 ID:jDwZWgRX.net]
下手に分かったふりせず疑問をぶつけるパニック君のようなレスはスレにとっては有益
逆に知ったかぶりして嘘を撒き散らす某オジのレスは害しかない

一緒に仕事してても伸びるのは断然前者のタイプ
後者は多少知識があってもチームの足を引っ張る老害タイプ

408 名前:デフォルトの名無しさん mailto:sage [2023/02/07(火) 11:56:13.05 ID:Yu/MJcLX.net]
>>407
知ったかぶりもだけど
ご飯論法的に毎回論点を捻じ曲げてくるのが悪質
スルー推奨

409 名前:デフォルトの名無しさん mailto:sage [2023/02/07(火) 12:39:13.84 ID:GmLWJf7C.net]
どの言語を使っていようがテスト設計とエラー処理設計は初心者と脱初心者を見分けるリトマス試験紙
チュートリアルやリファレンス読むだけでは身につかない

410 名前:デフォルトの名無しさん mailto:sage [2023/02/07(火) 13:41:38.43 ID:vPUoP0i3.net]
そう、IT土方必修



411 名前:デフォルトの名無しさん mailto:sage [2023/02/07(火) 20:09:18.77 ID:RZZKb5qe.net]
>>410
こういうバカが一人でも入ってくると現場は苦労するわな

412 名前:デフォルトの名無しさん mailto:sage [2023/02/07(火) 22:03:06.31 ID:u8XyY9YO.net]
今回のケースはRustのエラー処理を他の言語(C#あたり)の例外処理に寄せようとしてる感じ
「特定の例外クラスをcatchしたい」→「dyn Errorで投げてダウンキャストで分岐すればいい」みたいな
anyhowはそういう人のためにあるのかもしれない

オブジェクト指向言語専攻の人はRustのtraitを基底クラスの代わりに使いがちだよね
is-a継承はRustだとenumで表現できる場合が多いんだけど切り替えが難しいのかも

413 名前:デフォルトの名無しさん mailto:sage [2023/02/07(火) 22:27:27.04 ID:23ICgzsB.net]
単純にエラーの種類を列挙する意味がないときに使うだけやで

414 名前:デフォルトの名無しさん mailto:sage [2023/02/07(火) 23:09:28.73 ID:u8XyY9YO.net]
それならいいんだけど型キャストしてまで分岐するとか言ってる人がいたから
自分で分岐する範囲くらいは自分で列挙しとけって話

415 名前:デフォルトの名無しさん mailto:sage [2023/02/07(火) 23:53:31.04 ID:23ICgzsB.net]
下層から上がってくる99種類のエラーはログ吐かせるだけで、特別な処理したいエラーはひとつしかないのにいちいちenumに詰め直したりせんわな

416 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 00:04:28.76 ID:mV68xos2.net]

自分で分岐してエラー処理すんなら区別すべきエラーを決めるのは自分なのでanyhowやdyn Errorでダウンキャストしても問題ない

外から呼び出されるコードなら区別して処理するエラーを決めるのは呼び出し側なので区別できるようにenumで書く

417 名前:デフォルトの名無しさん [2023/02/08(水) 00:35:28.79 ID:ydIblX/+.net]
すまんが、これってなんでダメなの?
ブロックの最後に式を書いてるのに、なんでreturnって書かないとリターンしないの???
そもそもエラーの内容に書いてあるmismatched typesって、一体何と何のタイプがミスマッチなんなんだ・・・・
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d1833710038ed821593015e5382de11f
エロい人教えて!!!

418 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 01:51:02.48 ID:U3de6tMw.net]
>>417
else句が無いのでifの条件式がfalseの場合はif-expressionは()になるけど
ifの条件式がtrueの場合はif-expressionがi32になるのでミスマッチ

419 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 01:59:22.59 ID:W8WwzKcT.net]
>>415
ログを吐かせるだけでもエラーによってログの吐き方を変えたいこともよくある話なのでケースバイケース
99種類を2種類に詰め直して片方をerased typeにしたりする

420 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 07:28:48.49 ID:2c2bFNHO.net]
上位の関数でもかなり多数のケースに分けてエラー処理する必要な場合だと
個別にenumにエラー型を収容する方が有利なケースもある
もちろんその場合でもanyhowやdyn Errorに収容してダウンキャストしてもよい
enum matchとダウンキャストの実行時コストはほぼ同じで優劣はなく視認性も変わらない
enumを使うとコードが増える問題はあるがあとは好みの問題



421 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 10:45:01.05 ID:ENpYrX9l.net]
ダウンキャストは下位モジュールに不必要に依存することになるので選択の余地があるなら基本的には使うべきではない

自crateで定義したエラー型にダウンキャストするくらいならエラーを定義するついでにenum書いとけばいいだけ
他crateで定義したエラー型にダウンキャストしてるとバージョンアップ時にサイレントにキャストが失敗して動作が変わる

あくまで非常口であって使わざるをえないときはマイナス面を理解した上で注意深く使うもの

422 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 10:52:13.58 ID:fJPPomwd.net]
UnknownErrorにわざわざ詰め直したログ吐くしかできない99種類あったエラーと1種類の自クレートのMyErrorをenumで2つ列挙して分岐するのと
MyErrorも含めて100種全部dynで上げてMyErrorだけダウンキャストすることの間に大した違いはない

423 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 12:29:34.73 ID:/lg+THEr.net]
アプリケーション開発とライブラリ開発の2つの視点があって、それぞれで戦略が違うというのが大元にあるからそこは理解してもらわないとね。

424 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 12:40:19.14 ID:TursxKDi.net]
ライブラリでdyn Error使うと本体の型がpubじゃないときにめんどくさそう

425 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 12:45:18.46 ID:QfEWSkwW.net]
両者で大きく異なるよね
ただし既出のcargoやreqwestなど違いに関わらずダウンキャストを使っているコードも多いから
どっちだと良くてどっちだとダメというものでもない気がする

426 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 12:48:39.58 ID:QfEWSkwW.net]
424は422へのレスね

>>424
そこはenum作って収容しようがdyn Errorに収容しようが関係なくpubじゃない型はどうにもならないような

427 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 13:05:56.18 ID:B9DUhvwN.net]
>>422
どういう種類の変更に対してコードのどの部分に手を入れる必要が出てくるのかを考えてみるといいよ

428 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 13:15:25.12 ID:Fgr/3fzw.net]
求められてもない具体性のない中身のない全く役に立たないアドバイスは有害でしかない

429 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 13:35:42.99 ID:DnIJ53A+.net]
現実にdowncast_ref()が使われているアプリやライブラリが多数あり
それらが問題になったことはないのだから
downcast_ref()を嫌っている人は思い込みで好き嫌いに過ぎないことを理解しようぜ
enumを作っても下位のエラー型を突っ込むだけでは何も変わらない

430 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 14:12:14.99 ID:SqObziFu.net]
ここまで具体的なコード例なし



431 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 14:40:13.85 ID:J3DHyZUt.net]
前提条件付けて場合分けして考えろ
てかこんなことでスレの半分近くも消費すんな

432 名前:デフォルトの名無しさん [2023/02/08(水) 16:15:41.93 ID:ydIblX/+.net]
>>418
そうだったのか!returnを書いたら通るのも、そうするとどちらも戻り値が()同士で統一されるってことか!
ありがとう!全然わかんなかったぜ!

433 名前:デフォルトの名無しさん [2023/02/08(水) 16:16:54.39 ID:VvFQM19K.net]
>>418
>>417では無いが、そういう意味だったのか
単に厳し目にチェックしているからだと思っていた

434 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 17:13:58.11 ID:e6ub/0SO.net]
たぶんだけど「Rustでは値を返すのにreturnを省略できる」と誤解してるんじゃないかな
その誤解のためreturn bのreturnを省略してしまったと思われる

正しくは「Rustでは最後の値が返り値となる(のでreturnが不要)(だが使ってもよい)」
と「途中で返したい時はreturnを使う」

だから今回の例だと
if文の中では『途中だから』return bとbにreturnが必須
あるいは関数の最後をif-else式にしてしまえば『最後となるから』bにreturnは不要

435 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 17:28:24.72 ID:e6ub/0SO.net]
ちょっと誤解があるから追加
最後をif-else式にすれば全体に式returnのreturnが不要になる
そしてif-else式の中はreturnは不要というか付けない
そこにreturnを付けるとif-else式ではなぬif-else文になる

436 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 18:12:57.92 ID:uJD0QVJP.net]
文章を難読化しすぎやろw

437 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 18:22:49.80 ID:KYgqZ0R0.net]
面倒だから戻るところはすべてreturn書いてる

438 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 20:39:29.96 ID:EOwXjjdD.net]
return式の型は厳密には!なんだけど……
まあ後で知ればいいか

439 名前:デフォルトの名無しさん mailto:sage [2023/02/08(水) 20:50:18.79 ID:e6ub/0SO.net]
そのおかげでif式でreturnしつつelseで値を与えたりできるね

440 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 11:57:24.62 ID:w55r8U1C.net]
早期returnはバグにつながるから禁止が常識



441 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 12:14:59.38 ID:bVNNfLSa.net]
>>440
昔はそう言われたけど今はそんなカス風習廃れたしRustに持ち込まないでほしい。

442 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 12:15:50.03 ID:UhaInviD.net]
早期returnは(>>440みたいなアホが使うと)バグにつながるから禁止が常識

443 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 12:41:16.10 ID:S7fEOBGh.net]
わざわざ早期リターンのために?演算子なんて用意してるRustで早期リターン禁止とな?!

444 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 12:43:02.37 ID:EmRyIpwb.net]
スルースキル皆無か

445 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 13:10:12.86 ID:wPt4Q+MY.net]
なんで昔は早期returnがバグにつながると考えられてたの?
どう考えても早期returnしない方がバグにつながりやすいと思うんだが

446 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 14:20:08.85 ID:QqGr+Vdk.net]
もっと昔にgotoの使いすぎで制御構造がぐちゃぐちゃになったことへの反動で
複雑な制御構造は使わないようにしよう、という流れだったかと

447 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 14:55:47.47 ID:UhaInviD.net]
>>445
C言語時代の話な
例えばこういうパターンでメモリーリークしたりするバグがたくさんあった

f(...){
p = malloc(...);
...
if(...) return;
...
free(p);
}

448 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 15:21:57.59 ID:9WtqRr2n.net]
そのあたりも自動メモリ開放のRustなら大丈夫だね
if文で早期return/continue/breakしないと、どんどんifネストが深くなっていくのでそれを避けたい

449 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 15:37:28.09 ID:Ktnp537B.net]
>>447
リソース確保・解放するレイヤーとそれを使って処理を行うレイヤーを分ければよくない?

f(...){
p = malloc(...);
g(p, …);
free(p);
}

g(…) {
...
if(...) return;
...
}

ifのネストが浅くなっても逆に関数のネストが深くなりすぎて読みにくくなる側面があるということなのかな?

450 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 15:51:48.67 ID:oQtbOpVY.net]
>>449
分けましょうってルール化したくらいで完璧に守られるなら誰も苦労しないんだよな…
そのうち処理レイヤー側でmallocするやつが出てくるやつ



451 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 15:59:20.91 ID:Ieoj7bJI.net]
RAII無しでの話なんかRustに関係無いだろ。

452 名前:デフォルトの名無しさん [2023/02/09(木) 16:04:18.76 ID:1694Wm1I.net]
ifがネスとしていたりした場合に、returnみたいにif-expressionの方に結果を返したい時ってどうすればいいの?

453 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 16:22:54.26 ID:eQhq+cyr.net]
>>450
早期returnはやめましょうルールは完璧に守られる保証があると?

454 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 16:24:27.43 ID:g7YoScpU.net]
>>452
擬似コードでいいのでイメージを書いてくれ
でないと言いたいことが分からない

455 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 16:25:56.79 ID:VnFQyKoO.net]
>>452
最近入ったラベル付きブロックでbreak

https://rust-lang.github.io/rfcs/2046-label-break-value.html

456 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 16:36:32.32 ID:8ktpZl0b.net]
言語仕様的に可能でも規則で縛ることで安全を担保しようという方法は
いずれ失敗するからそういう要素は必ず言語側の仕様で保証すべき、というのがRustの思想なんだから
「あれは危険だから駄目、コーディング規則で縛る」という発想自体が間違ってる

457 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 16:43:33.27 ID:UhaInviD.net]
>>449
リソースが1つだけならいいかも知れないけど複数リソースが絡んでたりすると色々ややこしいコードになっちゃう
>>453
コードレビュー時に return 検索したら

458 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 16:44:45.59 ID:UhaInviD.net]
>>451
>>440 に言ってくれ

459 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 16:48:27.59 ID:jx1YaHu3.net]
>>457
なるほど
そういう方法だけに頼ってるなら早期returnのほうが見つけやすいわな

460 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 16:49:18.29 ID:9WtqRr2n.net]
こういうやつ?
let result = 'found: {
 for i in 0..100 {
  if f(i) {
   break 'found Some(i);
  }
 }
 None
};



461 名前:デフォルトの名無しさん [2023/02/09(木) 17:15:30.09 ID:1694Wm1I.net]
>>454-455
>>460
やりたかったのこれだ、せんきゅー!

462 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 17:27:44.71 ID:vSSl5weC.net]
最近はCでもcleanup属性というのが使えるんだな

463 名前:はちみつ餃子 mailto:sage [2023/02/09(木) 17:43:07.29 ID:zt0qN6wf.net]
>>445
構造化が重要視された時代がある。
順次・反復・分岐によって処理の流れを構築するという点から見ると
早期リターンは流れをすっとばして大ジャンプしてることになるので
コードを追うのを難しくすると考えられていた。
「出入口はひとつずつ」は基本思想だったんだよ。
構造化が不十分だった時代にまず構造化することが大事だったという話。

今では構造化が当たり前になったから次の段階として順次・反復・分岐という構造だけでは
上手く扱いづらい部分をどうやるのがいいのかという模索が続いてるわけ。

464 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 18:03:17.12 ID:9WtqRr2n.net]
戻るgotoは結局なんらかのループを表しているので
Rustならラベル付loopに指定continueで表せる
進むgotoは無制限ではなくラベル指定breakの大域脱出型に制限される
という認識で合ってる?

465 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 18:18:38.11 ID:xZSrodqJ.net]
>>455
なんか微妙な機能だな
関数化して早期returnさせる手間が嫌ということなんだろうけどそれなら||や&&オペレータをOptionやResult用に上書きできるようにした方がずっと使いやすい
tryブロックとの非対称性も気になる

466 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 18:30:28.03 ID:9WtqRr2n.net]
>>465
今までに既にあった機能のラベル付loop式のラベル指定breakという使われ方のうち
ループしない使われ方が多かったため事実上のシンタックスシュガーが導入されただけだよ
だから微妙な機能が追加されたという見方は正しくない

467 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 18:30:33.67 ID:QonGkYb5.net]
>>465
ほとんどの場合はこんなん使う前にその部分を関数に切り出すことを考えるべきというのはめちゃくちゃ言われてる
awaitとかResultとかライフタイムとかいろいろ絡んできたときに再利用もされない数行の処理のために長々と型を書かなくても済むのがユースケースのひとつと思われる

468 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 18:46:56.04 ID:RAzSpXh0.net]
>>466
シンタックスシュガーも機能やろがい
公式にもlanguage featureと書いてるぞい

469 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 18:50:34.43 ID:hFEBZw9k.net]
どうせなら仮変数みたいな変数割当機能も用意して、末尾最適化再帰風ループもできるようにならないかね。

470 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 18:53:10.62 ID:9WtqRr2n.net]
>>468
既に昔から存在していたloop式を
loopと書かなくてもよくなっただけだよ
今までは皆はloop式の最後をbreakすることでloopさせずにこの同じ機能を使っていた
今回でloopを省けるようになったため最後のbreakが不要とだけにすぎない
今さら文句をつけるのが不思議



471 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 19:02:26.27 ID:o9a7e9s5.net]
早期returnってファウラーのガード節の話じゃないん?
あの使い方する限り安全安心可読性改良にしかならないよな?

472 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 19:04:01.20 ID:EmRyIpwb.net]
>>471
ファウラーじゃなくてリーダブルコード?

473 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 19:05:50.10 ID:o9a7e9s5.net]
リーダブルコードは忘れたけど

part of martinfowler.com
https://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html

474 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 19:15:02.58 ID:9WtqRr2n.net]
if letでネストが深くならないように早期return等しようとすると無駄コードが膨らんでいた問題も
同時に導入されたlet elseによって解決されたね

475 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 19:24:14.80 ID:EmRyIpwb.net]
>>473
そうこれ、というか第1版からあるならファウラーが先なのね
失礼した

476 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 19:31:22.46 ID:Kxe1JjXm.net]
「ルールだからダメ(思考停止)」な人って結構いるよね

477 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 19:40:55.17 ID:rpwFU8e5.net]
ルールの背景を考えずに破ろうとするやつも多いけどな。

守破離は基本だろ。ブルースリーのパンチキックの逸話でもいいけど。

478 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 19:47:18.19 ID:Kxe1JjXm.net]
>>477
合理的なロジックがないという点で同類じゃね
「ルールだから問題ない(思考停止)」で他人に迷惑をかけるのも同じ
そして多くの場合無責任までセットだ

479 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 19:54:21.56 ID:bVNNfLSa.net]
そもそも失敗できなくするのがここ10年ぐらいのトレンドだろ。
だから静的型やRustが支持されるわけで。

480 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 20:07:33.02 ID:rpwFU8e5.net]
>>478
ルールについては「決定と実行の分離」という重要な側面があるよ。

頭のいい奴がルールを作れば、アホがルール通りに実行しても被害は少ない。アホがルールを破るよりよほどマシ。



481 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 20:20:31.75 ID:9WtqRr2n.net]
Rustの制御構文としては
昨年末の2つの追加で
従来は不便で需要が多かった形が無事に解決したから一段落かな

482 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 22:05:48.35 ID:nhsBAAgr.net]
>>465
わかる
旧世代言語のニオイがする

483 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 22:51:32.40 ID:YnVskMRN.net]
こういうの書くやつが出るから
基本は使わないほうがよさそうだな
https://github.com/rust-lang/rust/issues/48594/partials/load_more#issuecomment-1184213006

484 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 23:06:57.24 ID:QonGkYb5.net]

何らかの目的で大域脱出を用意すると必ず妙ちくりんな悪用を考える奴が出てくるんだよな

485 名前:はちみつ餃子 ◆8X2XSCHEME mailto:sage [2023/02/09(木) 23:22:20.06 ID:zt0qN6wf.net]
そういえばコンテナのイテレーションの順序が未規定なときに
順序に依存したコードを書かないように乱数でわざとデタラメな順序にしたら
乱数生成器として使うやつが出てきたって話があったな。

どんな機能も下手に使ったら無茶苦茶にしうるってのはもうどうしようもなくない?

486 名前:デフォルトの名無しさん mailto:sage [2023/02/09(木) 23:42:25.26 ID:iUuqvbE0.net]
>>56のが実現したらRFCの例は||で代替可
let result = (first_container.iter().find(|&&v| v > 0)
|| second_container.iter().find(|&&v| v < 0))
.unwrap_or(&0);

labelやbreakの手続き的なやり方よりこっちの方が汎用性も高いしrustの目指すべき方向に合ってると思う

487 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 01:49:50.47 ID:JoKDyp+E.net]
メソッド抽出は嫌
クロージャの即時実行も嫌
ラベル付きbreakならOK!
って感覚が俺には理解できんが
ニーズがあるならいいんじゃね

488 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 02:22:12.82 ID:KiCBMwJT.net]
>>487
関数切り出しやIIFEだと式の値はResult型になるようなところで、
ラベル付きブロックだとエラーまわりは親の関数に完全に任せて該当の式の値を生で返せる

489 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 02:35:52.13 ID:8y57Q10t.net]
ラベルでジャンプより、関数の入れ子の方が分かりやすくない?

490 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 03:36:08.11 ID:eoPLVAGF.net]
>>488
?オペレータ使えばいいだけなんだが?
逆にエラーまわりだけ親関数に任せるとかヤバくね?



491 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 06:59:25.26 ID:Fpp4vOr0.net]
>>489
ラベルでジャンプしていない
loop式の構文のloop抜きと動作も概念も全く同じだから
今回Rustはたまたま同じ構文を採用しただけ

例えば>>460の例は
ラベルを用いない別の新たな構文{{…}}を導入すればこうなる
let result = {{
 for i in 0..100 {
  if f(i) {
   return Some(i);
  }
 }
 None
}};
動作も意味も全く同じであり
ラベルにジャンプしていないことが理解できるだろう

492 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 07:32:00.75 ID:Fpp4vOr0.net]
そしてRustがなぜ今回の構文の形を採用したか
・returnでもbreakでも多重になった時にどれを終えるのか曖昧になるため何らかの指定は必要
・ラベルによる指定はRustの他の構文でも共通に既に使われており親和性がある
・returnの使用は混乱を防ぐために関数とクロージャーから返る位置付けのみに保ちたい
・既存のloop式と今回の構文はloopキーワードを除けば全く同じであり導入前はloop式で代替されていた

493 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 07:54:41.21 ID:Fpp4vOr0.net]
>>489
必要性に応じて関数として切り出すのも構わない
そして関数として分離した方が好ましい場合もあるだろう
しかし常に関数切り出しを強いられる言語だったとしたら煩雑すぎて機能不足と言えるから使い分けできることが必要

494 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 08:05:40.53 ID:nOIBi0US.net]
>>491
文脈読めなさ過ぎw

495 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 08:18:49.59 ID:Fpp4vOr0.net]
>>494
従来からforやloop式で使われてきた早期return(離脱)つまりRustでのラベル指定break
そして今回Rust導入されたブロック式での早期return(離脱)つまり同様に構文としてはラベル指定break
それらに対して「ラベルでジャンプ」とは何を言いたいのか?

496 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 08:34:37.12 ID:wb0Nj+xg.net]
>>486
短絡orに論理orを使うのは混乱の元だから、別の専用の記号を用意して欲しいわ。

497 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 08:39:40.06 ID:Fpp4vOr0.net]
>>496
遅延評価orの型が
現在はbool型のみに制限されているから
それをOption型などにも使えるようにしよう!という話じゃないかな

498 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 08:41:20.86 ID:KiCBMwJT.net]
>>490
関数に切り出した時点で「その範囲のResultの型」を考慮しなくちゃいけなくなるから?演算子では何も解決してないし、
切り出さなきゃ元からその関数の処理だから何もやばくないぞ

499 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 08:50:58.78 ID:Fpp4vOr0.net]
関数切り出しすると
その中でも継続して使う変数(値)を参照として全て渡してそれらの型宣言も改めて行なってと煩雑さとコードの重複が大きい
もちろん返り値型も型推論で済まなくなり明確に宣言しなければならなくなる

したがって関数切り出しの方が明確にメリットが上回るケースを除いて
適材適所でブロック式で済ませられるようになった今回の導入は大きな意義があると思う

500 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 09:14:00.68 ID:8y57Q10t.net]
関数切り出しじゃなくて、関数のネスト



501 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 09:39:52.23 ID:FTCkglUc.net]
>>491
動作も意味も全く同じとのことだが
その構文でネストしたブロックから抜けられるのかい?

502 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 09:47:31.36 ID:XC30Ey72.net]
>>496
今も||は「短絡論理OR」で区別されてないよ
短絡論理ORと論理ORを分けてる言語ってある?

503 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 09:58:49.88 ID:zTpuYOFQ.net]
5年もの歳月を費やしてstabilizeするほど意味ある機能じゃないよな
超ニッチなnice to haveなんだからこんな機能実装するくらいなら他の作業してくれよ

504 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 09:58:58.37 ID:f/xkkyji.net]
>>500
Rustで関数のネスト定義は可能だけどスコープを親関数内に限定するだけだよね
親関数の変数をもちろん操作できないので改めて引数も戻り値も全て型宣言して受け渡ししなければならない

505 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 10:00:29.07 ID:76BGvvFm.net]
>>500
関数のネストでやるためには
関数に切り出す必要があるから同じことを言ってるんじゃない?

506 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 10:06:08.19 ID:f/xkkyji.net]
>>501
forやloopを使ったときにどのbreakか区別できるようにラベルが付いてるだけでラベル付ブロック式のネストまでは元々求められていないんじゃないかな
たまたまラベル付となったからネストさせて指定して抜けることも可能なのかも知れないけどさ

507 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 11:35:14.97 ID:D7CjmUqS.net]
>>506
指定したラベル位置に制御を移すような動きのことを一般的にはジャンプと呼ぶ
ラベルで指定したブロックを”抜ける”と呼ぶ感覚ももちろん理解できるが同じようにジャンプと呼ぶ感覚くらいは理解してやれって話

508 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 12:14:15.40 ID:53cyCMdn.net]
>>503
ブロック式の早期離脱機能は同時に導入されたlet elseと並んでRustにとって必須の機能
これまではブロック式で早期離脱が出来なかったため代替処置として
・ブロックの代わりにわざわざクロージャを用意して即時実行する
・ループさせないのにloop式を目的外でブロック式として用いる
・関数として切り出して引数型や戻り型などコードが無駄に膨らむ
以上3通りの方法が苦しい回避処置として取られてきた
この問題が一気に解決した

509 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 13:14:46.92 ID:OY+cHUF0.net]
>>508
おまえホント壊れたレコードみたいだな
馬鹿の一つ覚えで繰り返し同じことしか言えないからおまえが出しゃばってくるとすぐスレが腐る

510 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 13:40:49.41 ID:icbsua9B.net]
オジさんは即時実行マンセー派だったのに宗旨替えしたのかw
と言っても忌み嫌われてた即時実行から半歩前進して半歩後退してるみたいなので実質進歩してないな



511 名前:デフォルトの名無しさん [2023/02/10(金) 14:05:25.21 ID:aIK+hWQq.net]
いわゆる Rewrite it in Rust といわれる
  https://zenn.dev/tako8ki/articles/2021-06-awesome-alternatives-in-rust
ものだが、CoreUtil代替もでてきたようだ。
  https://www.phoronix.com/news/Rust-Coreutils-uutils-2023

そのうち、ls や cp , mv みたいなものも実はRust実装でしたという時代がくるのか?

512 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 15:10:52.96 ID:p1oXUla5.net]
誰もが必ず使うエラーまわりには散々ボイラープレートを要求するくせに
ブロックからの早期returnが必要なくらいの処理を関数に切り出したくないという理由だけで
プチgoto入れちゃうのはバランス感覚おかしいわな

513 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 15:25:57.81 ID:EzUIw58a.net]
ブロック式も関数も複数の文をひとつの式にするものだから関数から早期returnできるならブロック式から早期breakできてもええやん😁

514 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 16:46:17.45 ID:ec863R6+.net]
returnやbreakのことをgoto扱いしてる人は頭おかしい
むしろgotoを排除するために現在の言語ほとんどに備えられている
ラベル付breakをサポートする言語も多い

515 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 17:26:28.28 ID:TiW7YUw7.net]
レスバしかしてねーなお前ら

516 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 17:37:10.71 ID:gd5eXGUi.net]
Rustの機能はすべて素晴らしいということにしないと気が済まない人がいるのはよく分かった

517 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 17:57:37.26 ID:8u6orso3.net]
マクロは強力なのはいいけど出来は悪いと思う

518 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 18:07:23.86 ID:VmkjxzjW.net]
Rust の機能が全て優れてるとは思わないけど ラベル付き break なんて揉めるような機能じゃないだろ...

519 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 18:07:48.18 ID:ec863R6+.net]
Rustに限らず早期return、早期breakはどの言語でも要

520 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 19:02:21.11 ID:MJOsdNRe.net]
ブロックからの脱出とジャンプを同列に考えるやつは勉強不足だと思うがね。

Rustのスタックフレーム志向とかを考えれば、ブロック出入り操作を重視するのは自然。逆にスタックフレームの局所性を破壊する例外フローとかジャンプは嫌われて当然だわ。
例外フローにおけるエスケープ解析て確立しているんだっけ?



521 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 19:02:40.14 ID:MoSIyINf.net]
規約で禁止していいレベルの機能
Avoid labelled break. Use functions instead.

522 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 19:05:14.63 ID:53cyCMdn.net]
>>509
唐突に発狂されても意味不明
反論があるなら技術的な話でお願いします

523 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 19:06:54.13 ID:MJOsdNRe.net]
>>521
関数みたいなブロックを作ればいいんじゃない?
あるいはブロックみたいな関数とか。

524 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 19:07:09.08 ID:MJOsdNRe.net]
>>521
関数みたいなブロックを作ればいいんじゃない?
あるいはブロックみたいな関数とか。

525 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 19:24:57.65 ID:VelAUwkm.net]
>>521
Rustには何年も前からラベル付breakがあります
今さら文句をつけている人はRustを知らずイチャモンを付けたいだけだとバレていますよ

メジャーなプログラミング言語の大半がラベル付breakを備えています
JavaでもSwiftにもGoもJavaScriptすらラベル付breakを持っています
プログラミングにおいて必須の機能だからです

逆にラベル付breakを持っていない代表的な言語がC/C++です
今回のRust叩きをしている犯人はいつもと同じ人だと分かります

526 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 19:52:12.29 ID:ec863R6+.net]
breakに対してジャンプだとかgotoだとかトンデモ発言が出ていたのはそういうことか
C/C++しか知らないと多重ループすらgotoで抜けるしかないもんな
そういう貧弱な世界しか知らない視野の狭い人だから必死にRustを叩いていたわけか

527 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 21:33:52.77 ID:zr0HQZhu.net]
前から常駐してるアンチRustのやつだろ
ばればれだがアンチとばれないように装いつつRustの色んな点を批判してきた
特にRustならではの機能とか新たな機能とかRustらしい書き方とかを嫌う

528 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 22:57:01.58 ID:9GdW2Tn6.net]
同じことしか言わないから自演丸分かりやんww

529 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 22:59:03.20 ID:Y2H2O9Fe.net]
>>525
大半の言語が備えてるラベル付breakはループから抜けるものでブロックから抜けるものじゃないぞ

530 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 23:14:34.63 ID:z32i1LMi.net]
swiftがdo statementでブロックスコープから抜ける機能を用意してるがtry/catchなしの形では誰も使ってない



531 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 23:16:17.28 ID:TiW7YUw7.net]
そんなことよりさっさとif let Some(c) = chars.next(); c.is_whitespace() {とかって書けるようになってほしい

532 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 23:22:50.62 ID:KiCBMwJT.net]
ブロックは「必ず1回で終了するループ」と解釈可能なのでループからのラベル指定breakがあるならブロックからもbreakで抜けられる方が自然

533 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 23:24:33.98 ID:PcQ6rbEj.net]
Javaも文法的にはループ以外でもラベル付きブレイク使えるけど絶対使わないな

534 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 23:32:27.37 ID:Qit9LgYB.net]
>>532
その理屈でいけばラベルなしブロックからもbreakで抜けられないとおかしくない?

535 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 23:37:03.68 ID:q3LdPEQ+.net]
RFCの例を4パターンで書いてみたけどラベル付きbreakは無いな
1か2のパターンに収まる形にリファクタリングする
大半の人がラベル付きbreakを選びたくなるようなサンプルはないのかな?

1. 関数化
2. Optionコンビネータ
3. クロージャ
4. ラベル付きbreak

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=e365b15243be65f5fc2d09a94324317e

536 名前:デフォルトの名無しさん mailto:sage [2023/02/10(金) 23:46:57.14 ID:XHs/nBWT.net]
流れと一切関係ないけど
rubyは一時期tapとbreakで値を返す文化?あったな
foo.tap {|x| bar} // selfつまりfooを返す
foo.tap {|x| break bar} // breakでbarを返す
foo.then {|x| bar} // ブロックの結果つまりbarを返す。今はthen使うのが素直。

537 名前:デフォルトの名無しさん mailto:sage [2023/02/11(土) 00:18:21.11 ID:VRz38Asr.net]
>>531
セミコロンじゃなくて&&だよね
stableになるのは半年後くらいじゃない

538 名前:デフォルトの名無しさん mailto:sage [2023/02/11(土) 00:22:48.96 ID:LT0L6YWb.net]
>>535
再利用しない前提ならクロージャを変数に束縛してしまえば3.も視野に入ると思うんだ
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=3159733485aa1a7ee3a1838637a3a097

539 名前:デフォルトの名無しさん mailto:sage [2023/02/11(土) 00:29:21.70 ID:N8U5Q6xc.net]
異なる種類のエラーを返す関数が絡んできたとき、ラベル指定breakのみエラーの合成を?演算子で関数境界に押し込められる
関数やクロージャだと「ブロック内のエラーを合成した型」を明示的に取り扱うことになって二度手間

540 名前:デフォルトの名無しさん mailto:sage [2023/02/11(土) 00:48:21.15 ID:C7Sk8k8l.net]
>>536
tapでbreakなんて初めて知ったわ
イテレータのメソッドチェーンの途中経過を出力する時にしか使ったことなかった



541 名前:デフォルトの名無しさん mailto:sage [2023/02/11(土) 01:02:10.14 ID:rZ1nyaTw.net]
>>538
これは同意

>>539
サンプルコード書いてみてよ

542 名前:デフォルトの名無しさん [2023/02/11(土) 01:49:22.40 ID:sVZS7q05.net]
すまんがRustlingsでまたちょっと教えてほしいんだけどさ
これ↓のListing 8-8の&mutって、一体どういう意味があるの???
https://doc.rust-lang.org/book/ch08-01-vectors.html
Rustlingsをやっていて、似たような場面で&mutなしでも動いちゃうように見えるけど・・・・状況が似て非なるものなんだろか・・・・・
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b4a253142ce1e394ba13bb0c2fc58f11

543 名前:デフォルトの名無しさん mailto:sage [2023/02/11(土) 02:18:23.31 ID:N8U5Q6xc.net]
>>542
詳細はトレイトとか Deref とか IntoIterator とか関連型とかその章ではまだ出て来てない概念が色々絡むが

for item in v の v に対して
Vec<T> を渡したら item は T になって所有権ごと持ってく
&Vec<T> を渡したら item は &T になって不変参照のイテレーションになる
&mut Vec<T> を渡したら item は &mut T になって可変参照のイテレーションになる


Vec<T>は DerefMut<Target=[T]> を実装しているから &mut Vec<T> は暗黙のうちに deref_mut のメソッドを通して &mut [T] に変換されて
その &mut [T] が IntoIterator<Item=&mut T> を実装しているからfor文で &mut T のイテレーションができる

544 名前:デフォルトの名無しさん mailto:sage [2023/02/11(土) 03:08:28.64 ID:ClzSOMcn.net]
>>535
その程度ならば型宣言で冗長になる関数化をするまでもないからブロック式でも十分かな
使い分けできるようにブロック式の不備を整備したRustの方針は正しいと思うよ

>>542
所有権を渡すのは消費尽くすときだけでその後も使いたい時は参照&か可変参照&mutを渡す
そのコードのv.iter_mut()の方に見かけ上&mutが見当たらないのはメソッド定義にそれがあるから
メソッドでは所有権を渡すか参照を渡すか可変参照を渡すかをその定義でselfか&selfか&mut selfか指定することでメソッド使用時に毎回指定しなくて済むようになっている

545 名前:デフォルトの名無しさん mailto:sage [2023/02/11(土) 03:56:21.21 ID:VRz38Asr.net]
>>542
vがVec<T>の場合
for i in &mut v {…} と
for i in v.iter_mut() {…} は同じ

前者は&mut Vec<T>のIntoIteratorトレイトのinto_iter()が呼ばれる
その中身はself.iter_mut()なので後者と同じになる

for loopはiterable(IntoIteratorを実装してるもの)を受け取って
そのinto_iter()を呼び出してからイテレートする仕組み
https://doc.rust-lang.org/std/iter/index.html#for-loops-and-intoiterator






[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<165KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef