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/
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