Rust part19 ..
[2ch|▼Menu]
2:デフォルトの名無しさん
23/01/17 12:41:51.84 esjs4yiD.net
たておつ

3:デフォルトの名無しさん
23/01/17 14:00:56.91 MqwPrlrO.net
89 それでも動く名無し 2023/01/10(火) 23:26:51.53 ID:pA5+SQtP0
痴漢ものAVと違ってこういうガチ痴漢は臨場感が違うわ
抵抗されて上手く行かなかったり、たまに他の客にバレて逃走してるからな
マジで興奮する
URLリンク(i.imgur.com)
URLリンク(i.imgur.com)
URLリンク(i.imgur.com)
URLリンク(gcolle.net)
520 名無しさん@ピンキー sage 2023/01/03(火) 21:36:57.85 ID:AS4vmq4R0
不朽の名作が復活していたので
URLリンク(i.imgur.com)
URLリンク(i.imgur.com)
URLリンク(gcolle.net)

4:デフォルトの名無しさん
23/01/17 14:01:08.20 MqwPrlrO.net
すみません、誤爆しました

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

6:デフォルトの名無しさん
23/01/17 14:25:12.33 IvlgRnTP.net
ここが新しいおちんぽスレと聞いて

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

8:デフォルトの名無しさん
23/01/17 16:35:46.70 +0g0VEsU.net
通報しといたよ

9:デフォルトの名無しさん
23/01/17 16:41:04.96 mmIRzxLT.net
はよ立て直せ

10:デフォルトの名無しさん
23/01/18 10:59:16.69 j7LzfbP6.net
ワッチョイ有効スレ
スレリンク(tech板)

11:デフォルトの名無しさん
23/01/18 12:30:23.66 NvrWVfIW.net
おちんぽまんまんスレ違いと聞いて

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

13:デフォルトの名無しさん
23/01/18 20:29:34.91 vXgVoSzN.net
if let Err(_)

14:デフォルトの名無しさん
23/01/18 20:41:58.72 CRD98AUE.net
>>13
サンキュー。行けた

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

26:デフォルトの名無しさん
23/01/19 20:51:26.80 kHXiKnOP.net
あ、違うか。unwrapできる理由を書くわけか。
paniced at 'ここでは 0 は渡ってこないので自信を持って除算する'
みたいな出力になるから割と恥ずかしいな。

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

28:はちみつ餃子
23/01/19 22:24:19.09 uAmZfzQm.net
>>27
自分意外が使う前提のときのほうが except が必要だと思う。
外部から与えられる情報が仕様外の場合 (事前条件が満たされない場合) など
使い方が誤っているときに起こりえるなら except で説明があったほうがいいんじゃない?
内部的なロジック的に起こりえないと確信しているところは unwrap でいいと思う。
間違いがあったときに panic! してくれることには変わりないしバックトレースも出せるんで、
特に必要だと思う箇所だけ説明を付けておけば十分でしょ。

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

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

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

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

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

34:デフォルトの名無しさん
23/01/20 13:36:20.52 pmLm7hT0.net
ちんちん!シュッ!シュッ!!シュッ!!!

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

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

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

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

39:デフォルトの名無しさん
23/01/21 18:30:23.18 /bIQjlWu.net
>>37
info!やerror!ってpanic!やexpectと本質的に変わらないような。いずれにしろ呼び出し側で文字列の加工が必要
GUIへの対応方法もよくわからない。開発時はもちろんコンソールへの出力を使うけど
運用中のエラー出力はGUIのポップアップメッセージがメインになるし
あとソースコードは600行弱くらいだけどリリースビルドで生成されるバイナリは800KB弱もあるんで
これ以上でかくしたくないというのもある

40:デフォルトの名無しさん
23/01/21 22:40:10.67 wag66I/R.net
ロガーを設定/生成するコード
ロガーを使うコード
ロガー自体のコード
それぞれ分けて考える
ロガーを使うコードではファイル出力だろうが標準出力だろうがinfo!やerror!でコードを変える必要はない
使うロガーを変えたり設定を変えたりする
ロギングライブラリを使うのは自前で作るのは面倒だから

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

42:デフォルトの名無しさん
23/01/22 02:45:54.00 DAK16wxY.net
平家蟹がかわいくないとか、こいつアンチか?

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

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

45:デフォルトの名無しさん
23/01/22 14:52:04.22 RMpOCJx1.net
>>41
モンタギュー蟹の方

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

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

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

49:デフォルトの名無しさん
23/01/25 16:39:27.19 5onhVltK.net
天才か?

50:デフォルトの名無しさん
23/01/25 16:40:49.73 GSIKYco3.net
過去の自分は他人だと思え、がプログラミングの基本

51:デフォルトの名無しさん
23/01/25 17:17:39.71 xORIlv/9.net
過去のことを忘れていても過去の自分が考えることは今の自分が考えることとあまり差がない。
名前の付け方とかは何度考えても同じような状況なら同じ名前を付けるし。
書くときに想定する読み手が全くの他人のときと未来の自分のときではちょっと違う意識があるな。

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

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

54:デフォルトの名無しさん
23/01/25 20:37:11.28 5EKz9Dxo.net
>>48
あるあるだね

55:デフォルトの名無しさん
23/01/25 20:38:19.94 xtWPaGBn.net
>>47
なんでpanicになるの?

56:デフォルトの名無しさん
23/01/25 21:43:02.36 jK9fbSTx.net
>>38
一度ポシャってるけど実装される可能性はあると思う
URLリンク(github.com)

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

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

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

60:デフォルトの名無しさん
23/01/26 11:09:10.89 QY5r5/0E.net
すまんが、これの解答はmutをつけろっていうことなのはわかるけどさ
URLリンク(github.com)
なんで8行目で所有権を失って9行目で代入できなくなったりしないの・・・・?

61:デフォルトの名無しさん
23/01/26 11:24:13.84 DDvWU5a2.net
>>60
これはもっともな疑問

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

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

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

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

64:デフォルトの名無しさん
23/01/26 15:25:17.84 MCrVnhV0.net
>>63
&TはCopyだからmoveしないよ

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

66:デフォルトの名無しさん
23/01/26 17:21:49.46 YuUaXpq9.net
implicitly reborrowedされるとhogeが&mut *hogeになるのか
勉強になった
ありがとう

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

68:デフォルトの名無しさん
23/01/26 19:48:43.33 16g2h/GU.net
>>60
変数が値を所有しているんだよ
値がムーブされて一度無効化された変数にも新しい値を所有させられるよ
例えば、その9行目でxが3を所有していなかったとしても新しい値を入れられるよ
URLリンク(play.rust-lang.org)

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

70:デフォルトの名無しさん
23/01/26 20:31:02.62 q1WzF/2m.net
>>53
だからバグじゃないよね?

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

72:デフォルトの名無しさん
23/01/26 21:14:28.71 GObOayQz.net
>>68
そりゃmutならなw

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

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

75:デフォルトの名無しさん
23/01/26 22:06:21.53 HEA6MC1t.net
Deref無しは流石にきついな
一気にRust書きたくなくなる気がする

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

77:60
23/01/27 11:24:22.85 CSClNfzp.net
教えてくれてるのは本当にありがたいんですが、訳がわかんないぽ・・・・

78:デフォルトの名無しさん
23/01/27 11:51:57.32 YDsF+xqw.net
>>77
何がわからないのか書いて

79:60
23/01/27 13:58:30.55 CSClNfzp.net
マクロが展開するコードがあって、そこに&がついてるってことなんですか?

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

81:デフォルトの名無しさん
23/01/27 19:13:43.59 q2LYouLt.net
&はついてるけどあなたの疑問とは関係ないと思う

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

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

84:はちみつ餃子
23/01/28 02:45:04.16 OM0pptP0.net
>>82
Rust の文化にあまり詳しいわけじゃないけど panic を呼び出すのって C/C++ で言うところの assert 的なもんでしょ。
普通に考えたら panic が呼ばれるのはモジュールの仕様に対して使い方が間違っているかリカバリ不可能な場合。
逆に言えば使い方が正しくてリカバリ可能な状況で panic になるべきではない。
モジュールの使い方が完璧に正しいプログラムを書いても panic が引き起こされてしまうなら panic の使い方のほうが間違ってる。
絶対に通信が確立する状況で使えという仕様を設定すりゃあ間違ってるのは使い方のほうではあるけどさー、
ネットワークでそれは不可能な前提じゃん? ありえない前提を元にするのは不毛だろ。

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

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

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

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

89:デフォルトの名無しさん
23/01/28 11:52:23.17 NqcfPhRT.net
>>86
MSの開発者を説得してくれ

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

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

92:デフォルトの名無しさん
23/01/28 14:59:51.08 pTjpQsNq.net
The Bookにある回復不可能かどうかという判断基準は曖昧であまり役に立たない
Resultを伝播させてトップレベルでログ出力でもしてabortさせるのに比べて
問題発生箇所でpanicさせるメリットは処理をinfallibleな関数として定義出来ること
逆に言えばバグでも無いのにinfallibleな関数呼び出しでpanicで落ちるような設計はそれ自体がバグの可能性大

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

94:デフォルトの名無しさん
23/01/28 17:59:00.91 b6xT90Ev.net
>>93
イミフ

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

96:デフォルトの名無しさん
23/01/28 21:12:57.88 ZIiiTUHL.net
>>95
イミフ その3

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

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

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

99:デフォルトの名無しさん
23/01/29 01:28:33.47 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:デフォルトの名無しさん
23/01/29 02:35:07.62 r5isV+tS.net
誰もpanicをResultに変換する話はしとらんやろ

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

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

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

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

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

106:デフォルトの名無しさん
23/01/29 15:29:55.13 yzACUqHq.net
まずは異常終了と正常終了を分断するメリットを知る必要がある

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

108:デフォルトの名無しさん
23/01/29 15:48:49.58 CZoRokqJ.net
panic!すべきかするまいか
URLリンク(doc.rust-jp.rs)

109:デフォルトの名無しさん
23/01/29 17:07:54.00 qjfBPBdR.net
>>107
The Bookの12章を復習して
URLリンク(doc.rust-lang.org)
ただThe Bookは他言語から来た人が最初に読むチュートリアルとして用意されてるものなのでカバーされてない内容も多々あるし深い解説がされてるわけでもない点は理解しておいた方がいいよ

110:はちみつ餃子
23/01/29 17:16:49.84 2OIx0YXk.net
標準ライブラリのマニュアルでも panic! はバグを説明するために使うということは書いてあるね。
URLリンク(doc.rust-lang.org)

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

112:デフォルトの名無しさん
23/01/29 18:41:07.89 qSgQK/Ke.net
>>105
Pythonのsys.exitと同じ感覚でstd::process::exit使うほうがはるかに問題では?
少なくとも異常終了に使う分にはpanic!のほうがsys.exitに近いと思うよ
sys.exit()
URLリンク(docs.python.org)
・SystemExit例外を投げるだけ
・メインスレッドで実行して、かつ例外がトップレベルまで捕捉されなければ、通常の例外機構に従ってプロセスが終了する
→finallyとかwithでリソース解放書けばちゃんと解放される
std::process::exit()
URLリンク(doc.rust-lang.org)
・無条件でプロセスを終了させる
・実行スレッドも他のスレッドも一切スタック巻き戻しが行われない
→デストラクタ呼ばれない

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

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

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

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

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

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

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

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

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

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

120:デフォルトの名無しさん
23/01/29 21:46:28.34 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:デフォルトの名無しさん
23/01/29 21:56:31.01 saQmfbkd.net
>TcpStreamにはset_read_timeoutでタイムアウトを設定すると、それ設定値以上でpanicを起こす。
readで設定したtimeout値を超えたらpanicすると言ってる?
少なくともリファレンスにはResultが返されるとあるんだが

122:デフォルトの名無しさん
23/01/29 21:57:37.90 K3YIwpIF.net
>>113
_exitはexit_groupのラップ関数だよ

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

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

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

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

127:デフォルトの名無しさん
23/01/29 22:38:36.38 yP5ym/xP.net
>>119
Rustでそのような形のpanicの使われ方はしませんしpanicは起きません
タイムアウトもio::Resultでio::Errorが返るだけです
これはC言語で書いてSO_RCVTIMEOでタイムアウト値を設定してreadで-1とerrnoが返る時と全く同じ状況です
言語独自の例外機構を持つ言語は複雑にしてややこしくしているだけなのでその考えをまず捨てるところからスタートしましょう

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

129:デフォルトの名無しさん
23/01/29 22:49:39.52 ZDOIjMr/.net
The BookにmainまでResultで戻す実践的な設計方法って解説されてる?
機能の説明はあっても実装するうえでどのようにしたらいいのかってところは抜けているような
ググるとstd::num::*を返す例、Stringを返す例、enumを返す例などが出てくるが
どのように使い分ければいいのかって点は不明
このスレ見ていてもこの部分に関する資料を提示している人は見かけないし
>>124
>箸の上げ下げレベルで手取り足取り教えてもらうことを期待し過ぎじゃないか
箸文化圏なら要らないだろうがスプーン・フォーク文化圏なら要るんじゃね
他所と大きく違うのであれば十分な説明を求められるのは当然では

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

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

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

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

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

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

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

137:デフォルトの名無しさん
23/01/30 00:00:50.47 M6Z3pSeY.net
すまん被ってた

138:デフォルトの名無しさん
23/01/30 00:02:36.60 RUd1b+83.net
>>132
なんでEを無くしたいの?

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

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

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

142:デフォルトの名無しさん
23/01/30 08:11:22.12 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:デフォルトの名無しさん
23/01/30 08:21:18.23 e4IM4WvI.net
もういいよ。お前はずっとpanic使っとけ。

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

145:デフォルトの名無しさん
23/01/30 08:31:46.93 uyNTp5VX.net
評判の悪いthe book 日本語版にすら使い分けの記述あるのに、それを無視して回復不能なエラー処理以外でpanicを推奨しようとするのは何なのかね。
エラー処理
Rustには例外が存在しません。代わりに、回復可能なエラーにはResult<T, E>値があり、 プログラムが回復不能なエラーに遭遇した時には、実行を中止するpanic!マクロがあります。

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

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

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

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

150:デフォルトの名無しさん
23/01/30 11:36:33.64 2ZbeByHM.net
>>142
ちゃんと読もう
そして全体の文脈を理解しよう
URLリンク(doc.rust-lang.org)

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

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

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

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

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

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

157:デフォルトの名無しさん
23/01/30 19:23:44.43 mT8msQLw.net
そうやってすぐ人格の問題にする

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


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

468日前に更新/165 KB
担当:undef