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

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

402:デフォルトの名無しさん
23/02/06 21:59:33.19 T23InEdz.net
自分の書いたレスを正しい正しいと
一人で連呼してて虚しくならないのかな

403:デフォルトの名無しさん
23/02/06 22:26:04.02 7y0OcpN0.net
エラー処理の網羅性という話は元々
関数からエラー値が返って来る可能性があるのに見落として処理せずに続行しちゃったり
あるいは例外が返って来る可能性があるのに見落として処理しないままでいたり
そういう見落としがよく起きていたから
いつどこでどんなエラー(or例外)が起きても処理漏れがないようにプログラミングしましょうという話
もちろんRustではResultで返せばコンパイル時点でエラーや警告が出るためエラー処理の網羅性は満たされます
Resultを返していればdyn Errorやanyhowを使っていてももちろん大丈夫
そしてエラー処理の分岐にそれらのダウンキャストを使うのも何ら問題なし

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

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

406:デフォルトの名無しさん
23/02/07 02:13:05.33 fMWAnbF1.net
anyhowは邪道だろ

407:デフォルトの名無しさん
23/02/07 10:30:33.69 jDwZWgRX.net
下手に分かったふりせず疑問をぶつけるパニック君のようなレスはスレにとっては有益
逆に知ったかぶりして嘘を撒き散らす某オジのレスは害しかない
一緒に仕事してても伸びるのは断然前者のタイプ
後者は多少知識があってもチームの足を引っ張る老害タイプ

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

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

410:デフォルトの名無しさん
23/02/07 13:41:38.43 vPUoP0i3.net
そう、IT土方必修

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

412:デフォルトの名無しさん
23/02/07 22:03:06.31 u8XyY9YO.net
今回のケースはRustのエラー処理を他の言語(C#あたり)の例外処理に寄せようとしてる感じ
「特定の例外クラスをcatchしたい」→「dyn Errorで投げてダウンキャストで分岐すればいい」みたいな
anyhowはそういう人のためにあるのかもしれない
オブジェクト指向言語専攻の人はRustのtraitを基底クラスの代わりに使いがちだよね
is-a継承はRustだとenumで表現できる場合が多いんだけど切り替えが難しいのかも

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

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

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

416:デフォルトの名無しさん
23/02/08 00:04:28.76 mV68xos2.net

自分で分岐してエラー処理すんなら区別すべきエラーを決めるのは自分なのでanyhowやdyn Errorでダウンキャストしても問題ない
外から呼び出されるコードなら区別して処理するエラーを決めるのは呼び出し側なので区別できるようにenumで書く

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

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

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

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

421:デフォルトの名無しさん
23/02/08 10:45:01.05 ENpYrX9l.net
ダウンキャストは下位モジュールに不必要に依存することになるので選択の余地があるなら基本的には使うべきではない
自crateで定義したエラー型にダウンキャストするくらいならエラーを定義するついでにenum書いとけばいいだけ
他crateで定義したエラー型にダウンキャストしてるとバージョンアップ時にサイレントにキャストが失敗して動作が変わる
あくまで非常口であって使わざるをえないときはマイナス面を理解した上で注意深く使うもの

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

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

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

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

426:デフォルトの名無しさん
23/02/08 12:48:39.58 QfEWSkwW.net
424は422へのレスね
>>424
そこはenum作って収容しようがdyn Errorに収容しようが関係なくpubじゃない型はどうにもならないような

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

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

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

430:デフォルトの名無しさん
23/02/08 14:12:14.99 SqObziFu.net
ここまで具体的なコード例なし

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

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

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

434:デフォルトの名無しさん
23/02/08 17:13:58.11 e6ub/0SO.net
たぶんだけど「Rustでは値を返すのにreturnを省略できる」と誤解してるんじゃないかな
その誤解のためreturn bのreturnを省略してしまったと思われる
正しくは「Rustでは最後の値が返り値となる(のでreturnが不要)(だが使ってもよい)」
と「途中で返したい時はreturnを使う」
だから今回の例だと
if文の中では『途中だから』return bとbにreturnが必須
あるいは関数の最後をif-else式にしてしまえば『最後となるから』bにreturnは不要

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

436:デフォルトの名無しさん
23/02/08 18:12:57.92 uJD0QVJP.net
文章を難読化しすぎやろw

437:デフォルトの名無しさん
23/02/08 18:22:49.80 KYgqZ0R0.net
面倒だから戻るところはすべてreturn書いてる

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

439:デフォルトの名無しさん
23/02/08 20:50:18.79 e6ub/0SO.net
そのおかげでif式でreturnしつつelseで値を与えたりできるね

440:デフォルトの名無しさん
23/02/09 11:57:24.62 w55r8U1C.net
早期returnはバグにつながるから禁止が常識

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

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

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

444:デフォルトの名無しさん
23/02/09 12:43:02.37 EmRyIpwb.net
スルースキル皆無か

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

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

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

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

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

449:デフォルトの名無しさん
23/02/09 15:37:28.09 Ktnp537B.net
>>447
リソース確保・解放するレイヤーとそれを使って処理を行うレイヤーを分ければよくない?
f(...){
p = malloc(...);
g(p, …);
free(p);
}
g(…) {
...
if(...) return;
...
}
ifのネストが浅くなっても逆に関数のネストが深くなりすぎて読みにくくなる側面があるということなのかな?

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

451:デフォルトの名無しさん
23/02/09 15:59:20.91 Ieoj7bJI.net
RAII無しでの話なんかRustに関係無いだろ。

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

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

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

455:デフォルトの名無しさん
23/02/09 16:25:56.79 VnFQyKoO.net
>>452
最近入ったラベル付きブロックでbreak

URLリンク(rust-lang.github.io)

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

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

458:デフォルトの名無しさん
23/02/09 16:44:45.59 UhaInviD.net
>>451
>>440 に言ってくれ

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

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

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

462:デフォルトの名無しさん
23/02/09 17:27:44.71 vSSl5weC.net
最近はCでもcleanup属性というのが使えるんだな

463:はちみつ餃子
23/02/09 17:43:07.29 zt0qN6wf.net
>>445
構造化が重要視された時代がある。
順次・反復・分岐によって処理の流れを構築するという点から見ると
早期リターンは流れをすっとばして大ジャンプしてることになるので
コードを追うのを難しくすると考えられていた。
「出入口はひとつずつ」は基本思想だったんだよ。
構造化が不十分だった時代にまず構造化することが大事だったという話。
今では構造化が当たり前になったから次の段階として順次・反復・分岐という構造だけでは
上手く扱いづらい部分をどうやるのがいいのかという模索が続いてるわけ。

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

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

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

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

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

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

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

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

472:デフォルトの名無しさん
23/02/09 19:04:01.20 EmRyIpwb.net
>>471
ファウラーじゃなくてリーダブルコード?

473:デフォルトの名無しさん
23/02/09 19:05:50.10 o9a7e9s5.net
リーダブルコードは忘れたけど
part of martinfowler.com
URLリンク(refactoring.com)

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

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

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

477:デフォルトの名無しさん
23/02/09 19:40:55.17 rpwFU8e5.net
ルールの背景を考えずに破ろうとするやつも多いけどな。
守破離は基本だろ。ブルースリーのパンチキックの逸話でもいいけど。

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

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

480:デフォルトの名無しさん
23/02/09 20:07:33.02 rpwFU8e5.net
>>478
ルールについては「決定と実行の分離」という重要な側面があるよ。
頭のいい奴がルールを作れば、アホがルール通りに実行しても被害は少ない。アホがルールを破るよりよほどマシ。

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

482:デフォルトの名無しさん
23/02/09 22:05:48.35 nhsBAAgr.net
>>465
わかる
旧世代言語のニオイがする

483:デフォルトの名無しさん
23/02/09 22:51:32.40 YnVskMRN.net
こういうの書くやつが出るから
基本は使わないほうがよさそうだな
URLリンク(github.com)

484:デフォルトの名無しさん
23/02/09 23:06:57.24 QonGkYb5.net

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

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

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

486:デフォルトの名無しさん
23/02/09 23:42:25.26 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:デフォルトの名無しさん
23/02/10 01:49:50.47 JoKDyp+E.net
メソッド抽出は嫌
クロージャの即時実行も嫌
ラベル付きbreakならOK!
って感覚が俺には理解できんが
ニーズがあるならいいんじゃね

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

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

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

491:デフォルトの名無しさん
23/02/10 06:59:25.26 Fpp4vOr0.net
>>489
ラベルでジャンプしていない
loop式の構文のloop抜きと動作も概念も全く同じだから
今回Rustはたまたま同じ構文を採用しただけ
例えば>>460の例は
ラベルを用いない別の新たな構文{{…}}を導入すればこうなる
let result = {{
 for i in 0..100 {
  if f(i) {
   return Some(i);
  }
 }
 None
}};
動作も意味も全く同じであり
ラベルにジャンプしていないことが理解できるだろう

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

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

494:デフォルトの名無しさん
23/02/10 08:05:40.53 nOIBi0US.net
>>491
文脈読めなさ過ぎw

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

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

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

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

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

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

500:デフォルトの名無しさん
23/02/10 09:14:00.68 8y57Q10t.net
関数切り出しじゃなくて、関数のネスト

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

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

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

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

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

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

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

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

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

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

511:デフォルトの名無しさん
23/02/10 14:05:25.21 aIK+hWQq.net
いわゆる Rewrite it in Rust といわれる
  URLリンク(zenn.dev)
ものだが、CoreUtil代替もでてきたようだ。
  URLリンク(www.phoronix.com)
そのうち、ls や cp , mv みたいなものも実はRust実装でしたという時代がくるのか?

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

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

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

515:デフォルトの名無しさん
23/02/10 17:26:28.28 TiW7YUw7.net
レスバしかしてねーなお前ら

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

517:デフォルトの名無しさん
23/02/10 17:57:37.26 8u6orso3.net
マクロは強力なのはいいけど出来は悪いと思う

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

519:デフォルトの名無しさん
23/02/10 18:07:48.18 ec863R6+.net
Rustに限らず早期return、早期breakはどの言語でも要

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

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

521:デフォルトの名無しさん
23/02/10 19:02:40.14 MoSIyINf.net
規約で禁止していいレベルの機能
Avoid labelled break. Use functions instead.

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

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

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

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

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

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

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

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

528:デフォルトの名無しさん
23/02/10 22:57:01.58 9GdW2Tn6.net
同じことしか言わないから自演丸分かりやんww

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

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

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

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

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

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

535:デフォルトの名無しさん
23/02/10 23:37:03.68 q3LdPEQ+.net
RFCの例を4パターンで書いてみたけどラベル付きbreakは無いな
1か2のパターンに収まる形にリファクタリングする
大半の人がラベル付きbreakを選びたくなるようなサンプルはないのかな?
1. 関数化
2. Optionコンビネータ
3. クロージャ
4. ラベル付きbreak
URLリンク(play.rust-lang.org)

536:デフォルトの名無しさん
23/02/10 23:46:57.14 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:デフォルトの名無しさん
23/02/11 00:18:21.11 VRz38Asr.net
>>531
セミコロンじゃなくて&&だよね
stableになるのは半年後くらいじゃない

538:デフォルトの名無しさん
23/02/11 00:22:48.96 LT0L6YWb.net
>>535
再利用しない前提ならクロージャを変数に束縛してしまえば3.も視野に入ると思うんだ
URLリンク(play.rust-lang.org)

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

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

541:デフォルトの名無しさん
23/02/11 01:02:10.14 rZ1nyaTw.net
>>538
これは同意
>>539
サンプルコード書いてみてよ

542:デフォルトの名無しさん
23/02/11 01:49:22.40 sVZS7q05.net
すまんがRustlingsでまたちょっと教えてほしいんだけどさ
これ↓のListing 8-8の&mutって、一体どういう意味があるの???
URLリンク(doc.rust-lang.org)
Rustlingsをやっていて、似たような場面で&mutなしでも動いちゃうように見えるけど・・・・状況が似て非なるものなんだろか・・・・・
URLリンク(play.rust-lang.org)

543:デフォルトの名無しさん
23/02/11 02:18:23.31 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:デフォルトの名無しさん
23/02/11 03:08:28.64 ClzSOMcn.net
>>535
その程度ならば型宣言で冗長になる関数化をするまでもないからブロック式でも十分かな
使い分けできるようにブロック式の不備を整備したRustの方針は正しいと思うよ
>>542
所有権を渡すのは消費尽くすときだけでその後も使いたい時は参照&か可変参照&mutを渡す
そのコードのv.iter_mut()の方に見かけ上&mutが見当たらないのはメソッド定義にそれがあるから
メソッドでは所有権を渡すか参照を渡すか可変参照を渡すかをその定義でselfか&selfか&mut selfか指定することでメソッド使用時に毎回指定しなくて済むようになっている

545:デフォルトの名無しさん
23/02/11 03:56:21.21 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()を呼び出してからイテレートする仕組み
URLリンク(doc.rust-lang.org)


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

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