Rust part12

■ このスレッドは過去ログ倉庫に格納されています
2021/08/24(火) 22:55:27.78ID:972JwtmU
公式
https://www.rust-lang.org/
https://blog.rust-lang.org/
https://github.com/rust-lang/rust

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

日本語の情報
https://rust-jp.rs/

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

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

※C++との比較は専用スレへ
C++ vs Rust
https://mevius.5ch.net/test/read.cgi/tech/1619219089/

前スレ
Rust part11
https://mevius.5ch.net/test/read.cgi/tech/1623857052/
2021/09/11(土) 22:08:56.74ID:UoP9tTBS
>>368
どうすれば良くなると思う?
2021/09/11(土) 22:10:09.25ID:HMdcT5ar
>>370
専用フォントを開発
2021/09/11(土) 23:22:27.41ID:7r8uHUGr
Javaより読みにくいとはさすがに思わんけど、
ジェネリクスが<>囲いなところとか、
そもそも中かっこ+セミコロンってのもどうなんだ、とか
Haskell並にとは言わんがもうちょっとかっこ少なくかけないのか、とか
思うところはいろいろとある
2021/09/11(土) 23:44:46.13ID:zUj2TAiQ
>>372
ジェネリクスが<>囲いなところ、ってメジャーなプログラミング言語のほとんどがそうだよね?
2021/09/11(土) 23:48:51.34ID:7r8uHUGr
>>373
その通りだけどあんまり筋がよくないことでもちらほらごく一部の界隈で話題になってるような
2021/09/12(日) 00:05:19.01ID:2NCRgpdh
変にRubyの影響受けてる部分は変えて欲しいなあ
2021/09/12(日) 00:20:02.96ID:Q5FBinyU
>>374
コンパイラ実装の問題なら承知した上で敢えて <> 採用してる
曖昧性の問題は turbofish で解決するなどコンパイラ実装を複雑にしない範囲で慣例的な記法に近づけている

>>375
Rubyの影響ってクロージャの記法のことかな?
2021/09/12(日) 00:39:47.78ID:qC6wZUfs
それはSmalltalkじゃないの?
2021/09/12(日) 00:49:53.96ID:Q5FBinyU
https://doc.rust-lang.org/reference/influences.html
ここによるとクロージャの記法はRuby由来
2021/09/12(日) 01:31:54.94ID:q/A4LK0H
クロージャの記法は各言語で様々だから大して気にならないけど
こう書きたいのに書けないのが悲しい

fn make_counter_closure(init: i32) -> impl FnMut() -> i32 {
 let mut counter = init;
 move || counter--
}

この件はRustやRubyだけでなくPythonやScalaやSwiftなどでも同じで
Swiftでは昔は出来たのに後から削除されたようだから最近はそういう傾向なの?
2021/09/12(日) 01:35:25.37ID:x/LB5mED
>>378
RubyのクロージャがSmalltalk由来だからどうなんだろ
2021/09/12(日) 07:25:17.64ID:+2JnoCR+
>>379
++と―はバグの温床だからそういう傾向
Swiftから削除されたのもRustでrejectされてるのも同じ理由
2021/09/12(日) 08:11:23.50ID:s09Gb+ph
だッさw
2021/09/12(日) 10:53:10.17ID:Q5FBinyU
>>380
起源をたどればそうかもしれないけどRustが直接的に影響を受けたのはRuby
2021/09/12(日) 12:43:40.70ID:7NdeG55C
ベストなジェネリクスの書き方ってなんだよ
Scalaみたいなのがいいの?
2021/09/12(日) 14:11:08.78ID:aiqNVBie
Scalaみたいに[]にするのもアリだけど配列がちょっとアレになるからさすがに避けたい気がする
D言語みたいに、例えば定義時には
struct(T) Foo { foo: T }
impl(T) Foo {
fn(T) new(foo: T) { Self { foo } }
}
みたいな感じにして、使用時には
let bar = Foo!i64::new(42);
って感じにするとか・・・?
実際に書いてみるとこれはこれで微妙な気もするが
2021/09/12(日) 14:19:29.99ID:UrK9UNLE
>>379
そこは
{ let result = counter; counter -= 1; result }
または
{ counter -= 1; counter + 1 }
になるの?
2021/09/12(日) 15:54:09.04ID:aiqNVBie
move || { counter-=1; counter }では???
2021/09/12(日) 15:59:39.60ID:lBuMyCBZ
>>387
それは後置デクリメントになっていない
2021/09/12(日) 16:29:00.55ID:aiqNVBie
後置であるということをそもそも認識できていなかった、やっべえ
2021/09/12(日) 16:37:25.63ID:458u6HPV
まさにバグの温床となりうることが示されたな
2021/09/12(日) 16:48:32.00ID:Q5FBinyU
>>385
初期Rustは [] だったけどまさに配列と被るからと言う理由で <> にした
C++と親和性のある構文を目指しているので <> 以外は採用されにくいと思う
2021/09/12(日) 22:21:50.69ID:s09Gb+ph
>>387
見ろ!Rustがゴミのようだ!
2021/09/13(月) 00:58:36.15ID:1X9d0oCW
型変数を明示しなきゃならないのは汎用プログラミング言語の欠点だよな
2021/09/13(月) 01:54:16.68ID:+ZZ666OR
何言ってんだこのバカ
2021/09/13(月) 11:03:41.66ID:HWJQ0k95
let mut counter = init + 1;
move || { counter -= 1; counter }

これが普通だと思うのは俺だけか?
2021/09/13(月) 16:07:27.15ID:1X9d0oCW
>>395
Rubyだと普通にそういう書き方するから特に違和感はないな
2021/09/14(火) 21:41:07.14ID:qEUG/jlq
配列がusizeだけなのを何とかして欲しい
i32 as usizeとかいちいち面倒
2021/09/14(火) 21:52:21.64ID:yDfeC3hP
>>397
普通に開発していればむしろusizeという別の型になってるおかげでミスなどに気付けて助かったことある人多いと思う
i32と別になっていることは非常に重要
2021/09/14(火) 23:13:54.76ID:/xeH/JpQ
usizeだとうっかりマイナスにしちゃって死ぬことがある
デバッグビルドならぱにくって気づくけど、
テストすり抜けちゃうとやばい
2021/09/14(火) 23:25:50.44ID:G8gCvJ5V
i32は流石にどうかと思うけど
グリッドの4-隣接とか8-隣接をforで回すときに中心からの差分で表現したくて、
isizeとusizeでガチャガチャ変換したときはちょっとウザいなーとは思った
2021/09/14(火) 23:35:48.81ID:9cp1Eg6y
impl From<u16> for usize はあるのに u32 はないのが面倒
usize のサイズがプラットフォーム依存なのは分かるけど毎回 trt_from().unwap() したくない
2021/09/15(水) 06:35:42.54ID:21ZYJzvz
Rustの難しさってある程度マスターしたあとは納得の難しさなんですか?

面倒だなー。でも(メモリ安全のためには)しょうがないか〜、みたいな
2021/09/15(水) 07:06:01.76ID:WxLXvftP
バカ矯正用補助輪付言語の難しさ
2021/09/15(水) 07:55:49.68ID:nFHSO/L2
補助輪なし言語でバグなしプログラム作れたらどこに行っても採用されると思うよ
2021/09/15(水) 08:36:21.78ID:P0HV9c3B
>>401
asでいけないっけ
2021/09/15(水) 09:04:47.19ID:77IP/X5S
>>405
asでも良いけどreleaseだとオーバーフローチェックしてくれないから心許ない
constの文脈だとunwrap使えないからas使わざるを得ないけど
2021/09/15(水) 09:15:01.47ID:P0HV9c3B
オーバーフローの懸念がある文脈ならtry_fromはしょうがないのでは
usizeがu32以上のプラットフォームだけ想定するならasでいいように思えちゃうんだけど
2021/09/15(水) 09:44:19.90ID:77IP/X5S
asを使うとu32から別の型に変更したときに修正漏れのリスクがあるのが気になってしまう
まあfrom相当のユーティリティ関数自分で用意すれば良いか
2021/09/15(水) 15:12:38.68ID:6EsPXkcj
>>398
じゃあunsafe時には許可して欲しい
2021/09/15(水) 15:24:13.77ID:a6LjJ0wO
暗黙の型変換が増えるのはやだよ
2021/09/15(水) 20:24:30.93ID:77IP/X5S
緩く簡単に書きたい人向けの言語じゃないよね全体的に
2021/09/15(水) 21:01:30.58ID:AIQN4pXi
それはそう
緩く簡単に書けるせいで起きていた全てのバグを撲滅したい、的な執念を感じる
2021/09/15(水) 21:30:37.23ID:rqQTOJGj
IntelliJ Rust pluginの新バージョン、関数とかの補完を機械学習でやるんだってさ
すごいね
試してないけど
2021/09/16(木) 00:03:22.08ID:5v2yv6GZ
誰も見ていなければ海や川でも裸で泳ぐCちゃんと
温泉の女湯でも深夜一人で水着で入るRustちゃん
2021/09/16(木) 00:56:52.16ID:sz29YBQA
エラーハンドリング可能な形ですっきりしたルールを定義できるならやればいいんだけど
現実にそういう上手い方法がないなら煩雑でも変換の手順を書くしかない。
2021/09/16(木) 01:12:36.12ID:Efcezeu+
低レイヤーいじる言語のエラー処理内容の粒度はそれこそプログラムごとに違うとしか言いようがない。
だから仕方ない。
2021/09/16(木) 05:10:39.16ID:7K5k42SQ
>>414
泳いでるのをDQNに見つかって乱暴されるCちゃん
そもそもDQNに覗かれるような温泉には入らないRustちゃん
2021/09/16(木) 05:50:12.68ID:P9SoBPvJ
おっきしてきた
2021/09/16(木) 06:27:10.25ID:s4mLRLKS
椎ちゃんの方逝くわw
2021/09/16(木) 18:55:26.69ID:cHl8Y0Er
as usize祭り絶賛開催中

unsafe fn calc(a_index: isize, b_index: isize) -> isize {
 if a_index == a.len() as isize { return 0; };
 let mut res: isize = 0;
 for i in b_index..b.len() as isize {
  if a[a_index as usize] == b[b_index as usize] {
   res = res.max(calc(a_index + 1, b_index + 1) + 1);
  }
 }
 res
}
2021/09/16(木) 19:34:21.47ID:vxj0ze2Y
>>420
関数に定義されていない変数が使われまくり
forループの中に変動変数がなく毎回同じ実行
キチガイのコードを読むべきでなかった
2021/09/16(木) 19:36:15.88ID:cHl8Y0Er
unsafeだしな

そして、その指摘にas usizeを擁護(容認)する意見は皆無だっていう
2021/09/16(木) 19:38:22.07ID:cHl8Y0Er
あと祭り発生中の実況だったので稼働するコードではなく、

if a[a_index as usize] == b[i as usize] {
}

と修正した
2021/09/16(木) 20:03:32.03ID:Y8GNLhYC
なんでunsafeなのかもわからないしなんでusizeじゃなくてisizeを受け取るのかもわからん
2021/09/16(木) 20:06:54.23ID:Y8GNLhYC
ああ、aとbグローバル変数なんかこれ?
2021/09/16(木) 20:47:15.02ID:cHl8Y0Er
引数がマイナスになることもあるので条件判断の必要からisizeなんだよね
もしusizeを引数にするとしても、引数に渡すところでisize as usizeになるので、やっぱりusize祭りが大発生

お祭りワッショイワッショイ
2021/09/16(木) 21:30:12.52ID:+FxVjnil
引数がマイナスになるならチェックしないと範囲外アクセスするだろ馬鹿か?
2021/09/16(木) 22:25:53.04ID:XSar1IoX
今どきIndex使って回すとか化石脳かよ
2021/09/16(木) 22:48:14.07ID:VRkuCUuZ
ボロクソワロタ
2021/09/16(木) 23:11:45.54ID:C/6oeybD
>>425
グローバル変数を使うのはありえないな
staticは使ってもモジュール内に閉じ込める
どの言語でも常識
2021/09/17(金) 01:14:24.53ID:+px3FZ+H
グローバル変数小文字にしたら警告出なかったっけ
2021/09/17(金) 03:56:57.86ID:L8yNiQtv
そもそもusizeで受け取って呼び出し側でケアすべきやろ
2021/09/17(金) 13:27:45.55ID:5NPaLNkl
>>412
経験的に、縛れば縛るほど最終的にはラクできるようなのを皆知ってると思う
ラクに書けるような言語は一見いいのだが
人間が生まれ持って自堕落であるのを伴って
最終的には苦しみをもたらすことになるコードを書いてしまう
2021/09/17(金) 15:13:45.88ID:dr0oo8mV
>>420も煽りのつもりで普段書いてないrustを
イキって書いたんだろうけど
煽り返された上にクソコードが掲示板に一生残るのは辛いよなあ
2021/09/17(金) 15:20:07.79ID:0JdlCgnp
3歩あるけば忘れるからヘーキヘーキ
2021/09/17(金) 16:32:00.60ID:5ZlSq2T+
いきなり unsafe fn とか書いてるあたり普段からrust書いるが競プロとかでついた変な癖を引きずってる人だと思う
余計悪いが
2021/09/17(金) 17:02:49.25ID:+63qaQLV
>>420
これって何するコードなの?
2021/09/17(金) 18:51:16.87ID:s3DmK0IG
>>437
ゴミカスコード力を披露するコードだよ
Rustどうこう言うやつはこのレベルが多い
2021/09/17(金) 20:36:20.90ID:B1Ewzio/
usize祭り絶賛発生中

while !next_pos.is_empty() {
 let mut tmp_next_pos: Vec<(i32, i32)> = Vec::new();
 for &(n_yr, n_xc) in &next_pos {
  map[n_yr as usize][n_xc as usize] = 2;

  for (a_yr, a_xc) in around(n_yr, n_xc) {
   if a_yr >= 0 && a_yr < m_yr + 2 && a_xc >= 0 && a_xc < m_xc + 2 {
    if map[a_yr as usize][a_xc as usize] == 0 {
     map[a_yr as usize][a_xc as usize] = 2;
     tmp_next_pos.push((a_yr, a_xc))
    }
    if map[a_yr as usize][a_xc as usize] == 1 {
     total += 1;
    }
   }
  }
 }
 next_pos = tmp_next_pos;
}
2021/09/17(金) 21:04:31.14ID:dr0oo8mV
>>439
しつこいなw
2021/09/17(金) 21:09:35.15ID:j5AVpFMs
isize ってどういう時に使います?
添字は基本的に usize しか使いませんし符号付き整数が欲しくなったらi32かi64で大体事足りるのでいまいち使い所が分かってません
2021/09/17(金) 21:43:47.45ID:hv2MZm4l
添え字に使う値を算出する途中計算で負数が必要になったら isize が妥当という場合もある。
443デフォルトの名無しさん
垢版 |
2021/09/17(金) 21:44:59.72ID:NEgFw8y9
can isize and usize be different in rust?
Can isize and usize be different? Both of them can be used for memory size, index, offset.
Since usize is used for arrays why don't we just have usize
I am new to Rust so this might be a basic question.

・usize cannot be negative and is generally used for memory addresses, positions, indices, lengths (or sizes!).
・isize can be negative, and is generally used for offsets to addresses, positions, indices, or lengths.

https://stackoverflow.com/questions/55506647/can-isize-and-usize-be-different-in-rust
意識高い系がウンコードを量産し罵倒するクソスレ
2021/09/17(金) 21:45:51.61ID:B1Ewzio/
そして、その結果、as usize祭りにもなる場合もある
2021/09/17(金) 21:51:17.48ID:2U7psvzf
>>432
経験的に縛れば縛るほど脱法行為が横行する。
446デフォルトの名無しさん
垢版 |
2021/09/17(金) 22:20:51.81ID:so2YCyjR
RustlingsをReplitで動かして学習したいのですが、これってrustlingsコマンドはどうやって動かすのですか?
https://github.com/rust-lang/rustlings
公式サイトが用意しているReplitの環境で学習をやりたいのです

よろしくお願いします
2021/09/17(金) 23:24:24.54ID:L8yNiQtv
>>446
ReplitのRustのバージョンが古くて(1.44)ビルド失敗するっぽい
見た感じローカルでやるのとそんな変わらん気がするから、
こだわりないならローカルでやるのが吉
この環境ビルドむっちゃくちゃ遅いし
2021/09/17(金) 23:26:48.18ID:qc9SKwMT
>>439
なぜそんなに下手なの?
配列のインデックスを取り出して配列をアクセスしてるだけなら
そのインデックスは最初からusize型にしておくだけてしょ
2021/09/17(金) 23:34:57.92ID:L8yNiQtv
>>445
脱法行為もなにも>>420のコードで負のindex渡されたらおかしくなるやんけ
2021/09/17(金) 23:57:58.10ID:L8yNiQtv
とはいえasナントカが一部のシチュエーションでめんどくさくなることはある(主に競プロ)

let (h, w) = (100usize, 100usize); // 多くの箇所ではusizeとして扱っている
let grid = vec![vec![0; w]; h]; // 横幅w 縦幅h 左上のマスの座標(0,0)のgrid

// 省略(なんかいろいろやる)

let (x, y) = some_func(); // 着目対象となるgridのマスの位置を(usize, usize)で取得

// (x, y)の上下左右のマスを対象になにかやる
for &(dx, dy) = &[(1i32, 0i32), (-1, 0), (0, 1), (0, -1)] {
let (x2, y2) = (x as i32 + dx, y as i32 + dy);
if x2 < 0 || x2 >= w as i32 || y2 < 0 || y2 >= h as i32 {
continue; // x2,y2がgridからはみ出してたら処理飛ばす
}
let (x2, y2) = (x2 as usize, y2 as usize); // できるだけusizeで処理したいので
// 省略(x2, y2を使っていろいろやる)
}

上下左右調べたいときに負の値が出てくるのがめんどくさい

一応workaroundはあって、for以下をこうする手がある
!0が2の補数的には-1として扱えるのでオーバーフローOKな足し算をする

for &(dx, dy) = &[(1usize, 0usize), (!0, 0), (0, 1), (0, !0)] {
let (x2, y2) = (x.wrapping_add(dx), y.wrapping_add(dy));
if x2 >= w || y2 >= h {
continue; // x2,y2がgridからはみ出してたら処理飛ばす
}
// 省略(x2, y2を使っていろいろやる)
}
2021/09/18(土) 00:02:40.07ID:WtcFUHdh
競技プログラミングは
正しいプログラミングスタイルから離れていく悪です
競技プログラミングスタイルな人と一緒に開発したい人は存在しないでしょう
2021/09/18(土) 00:04:38.74ID:JD4YYnZP
正当なスタイルが分かった上で競技としての割り切り方も分かっているなら問題ないんだけど、
競技から学ぶと変な癖が付きやすいというのは私も感じるなぁ。
2021/09/18(土) 00:15:51.96ID:NeCiGTRe
>>441
off_tとかptrdiff_tの代わり
例えば <*const T>::offset なんかはisizeを引数に取る
2021/09/18(土) 00:21:57.18ID:NeCiGTRe
>>450
自分はだいたい座標やwidth/heightはi32で扱って
indexへの変換処理を関数に抽出してそこでusizeに変えてる
一次元配列に二次元データ入れるときも自然に書ける
455デフォルトの名無しさん
垢版 |
2021/09/18(土) 01:57:08.86ID:T/YDtroe
type off_t = i64;(64bitOS)だからisizeを使うという発想は分かる。
でも厳密にはRustにNonZeroなどがある以上は、"本来は"実装されたfnが正常に動作する数値範囲があり
プリミティブ型で数値範囲を再定義し型定義出来ると便利だけど…、Type Aliasがあるのに無いのが辛い。
別言語の例
type Natural = range[0 .. high(int)]
type RegisteredPort = range[1024..49151, int]
type SomeSignedInt = int | int8 | int16 | int32 | int64
反対だ、コンパイルが遅くなるだけだという意見も絶対に認めない!もあるが、上記のNonZeroなどを見ると
将来的には実装されるのではなかろうか、いやヌルポインタ最適化のためのNonZeroだから入らないのでは?
という意見も分かるが…
またas演算子でキャストは安全だという話だが、符号付きから符号無しへの変換は、当然、どういう結果に
なるかを知っているべきだが、基本的な事をすっ飛ばす人も多いし、負を許容するoffsetが明確かどうかは
コードをすべて追わないと分からない場合が多い。なおこれが出来ると、コード中のキャスト変換が減るので
動作も早くなると思われるし、fnにした時の引数チェックも行わなくても良い状況が期待できる。
現実的に今のバージョンならindexもoffsetもisizeで作り、負を許容できない所にチェックを入れるだけで
as usizeは使わなくて良い箇所なら使わない。
2021/09/18(土) 09:35:47.96ID:z3n3Kv/4
>>450
let mut test = 100_usize;
アンダースコア使うと読みやすいぞ。おぬぬめ
2021/09/18(土) 11:21:13.85ID:I+biH5jK
winitのmasterでstdwebのサポートが切られてweb_sysに一本化されていた
stdwebってオワコンになりつつあるのかな?
2021/09/18(土) 17:05:43.72ID:NeCiGTRe
>>455
NonZeroはOptionとかのサイズ最適化やポインタの値がnullでないことを示すのが主目的なので
汎用的な範囲を組み込み型で示すのはちょっと違うかと
必要ならnewtypeパターンで自分で作ればよい
459デフォルトの名無しさん
垢版 |
2021/09/18(土) 17:29:18.29ID:1LwUu6qJ
配列がusizeなのはpythonなんかのa[-1]の最後尾アクセスを見てると、なぜそんな言語仕様にしたのかと
off_tなんかを見ると不思議に思う。いずれも Index bounds checkが掛るのに。符号無し64bitの巨大な
配列が欲しかったから?でもi128とかあるし
460デフォルトの名無しさん
垢版 |
2021/09/18(土) 17:47:44.01ID:2OOJm5Lf
インデックスiが実行時に決まるとき
配列のアクセスを内部的には *(p + i) にしたかったからじゃないかな
マイナスのとき〜っていう分岐をそこに入れずに最速でアクセスしたかったと
2021/09/18(土) 18:02:33.71ID:z3n3Kv/4
>>459
>符号無し64bitの巨大な配列が欲しかったから?
配列にマイナスの値は使わないんだから、そのぶんMAXの数を増やしたほうが
オーバーフローしにくいから安全だろってことらしい

でもどうせi32 as usizeとかi64 as usizeするから意味ないんですけどね!
462デフォルトの名無しさん
垢版 |
2021/09/19(日) 12:46:43.77ID:/yxUr6Cy
>>451
ほんそれ
めっちゃ判る
2021/09/19(日) 12:55:45.99ID:HwX1dH8g
>>459
32bit環境だとisizeにするとbyte配列が2GBくらいしか扱えないからじゃないのかね
ついでに一応16bit環境もサポートしてるみたいだし
2021/09/19(日) 15:08:42.28ID:i7fTqS33
競プロの書き方を仕事でするわけないだろ
何言ってるんだ
2021/09/19(日) 22:06:10.71ID:0p9m0gya
してるバカがいるから言ってんだよバカ。
2021/09/19(日) 22:13:07.84ID:xwERW7V5
矯正してやれ
2021/09/19(日) 22:58:17.41ID:i7fTqS33
アホか
競プロと仕事、書いてる時間がどっちが長いと思ってる
競プロは趣味 仕事で書いてるほうが圧倒的に長い
競プロでの書き方が仕事に引きずられることがあっても逆はない

そういうヤツがいるとか嘘をついてまで、
競プロに難癖つける理由がまったく理解できんわ
2021/09/19(日) 23:07:40.22ID:k8GedCcQ
お前が競プロスタイルで仕事するかどうかの話じゃないし、競プロに難癖つけてもいない
2021/09/19(日) 23:52:05.14ID:2t5v/hEZ
競プロRustスレを専用に立てて分離するのがベストな解決かな。
大多数を占める普通のRustプログラミングをする人たちにとっては役に立たない、特殊な競プロのコーティング方法が書かれても、批判議論に陥りがちでお互いにメリットないと思うのです。
2021/09/19(日) 23:53:50.32ID:i7fTqS33
難癖つけてるだろ

> 競技プログラミングは
> 正しいプログラミングスタイルから離れていく悪です

からの流れだからな
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況