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/10(金) 01:38:58.21ID:t0Gbnfvj
>>352
なるほど
勉強になりました
ありがとん
2021/09/10(金) 01:44:26.77ID:59f2QwjZ
>>351
Stringはヒープ上なのでstructの中でCopyは無理

>>352
そのStringも使わずにこれでいけますね
#[derive(Clone,Copy,Debug)]
struct St {
s: &'static str,
}
fn main() {
let ar = [St {s: &"str"}; 10];
println!("{:?}", ar);
}
2021/09/10(金) 05:44:54.18ID:XIGB6bHM
もはやご希望のものかどうかはわからんが

#[derive(Clone)]
struct St{
s: String
}

fn main(){
let ar = vec![St {s: String::from("str")}; 10];
}

CopyをCloneして配列をvecにしただけ
2021/09/10(金) 06:59:27.65ID:59f2QwjZ
>>355
vec!は単なるマクロでVec作ってるだけなので
それだと動的にヒープにString作って
そのVecを動的にヒープに作ってる
一方で>>354はヒープを全く使わないという差ですね
2021/09/10(金) 07:55:51.69ID:tPSWyt2L
>>354
>そのStringも使わずにこれでいけますね
それ>>352に書いてるのと同じじゃんw
2021/09/10(金) 13:58:45.81ID:iOAXb/4V
>>351
その後の用途によって7通りのやり方がある

let st = St {s: &"str"}; の場合は
let ar = [st; 10];
let ar = [&st; 10];
let ar = vec![st; 10];
let ar = vec![&st; 10]; の4通りが使い分け可能で
1番目はまとめて let ar = [St {s: &"str"}; 10];
3番目はまとめて let ar = vec![St {s: &"str"}; 10]; と省略可能
2番めと4番目が省略できない理由は参照なのに実体が変数にバインドされていないため

let st = St {s: String::from("str")}; の場合は
let ar = [st; 10]; の1番目だけは出来なくて
let ar = [&st; 10];
let ar = vec![st; 10];
let ar = vec![&st; 10]; の3通りが可能
3番目はまとめて let ar3 = vec![St {s: String::from("str")}; 10]; と省略可能
1番目が出来ない理由はヒープ上に作られるStringを暗黙的にコピーできないため
2021/09/10(金) 15:18:43.49ID:ylBsVH1G
無駄な長文乙
360デフォルトの名無しさん
垢版 |
2021/09/11(土) 02:12:58.97ID:xfwty4qw
数百行程度で、Rustらしいコードの例ってありませんか?
2021/09/11(土) 02:31:10.17ID:PFLibieQ
>>360
何に使うん?
紹介プレゼンとか?
362デフォルトの名無しさん
垢版 |
2021/09/11(土) 02:47:02.21ID:xfwty4qw
>>361
学習のために自分で読むだけです
2021/09/11(土) 02:58:05.44ID:s9euJTi1
現状はどのレベル?
とりあえず入門書は読み終わったって感じ?
2021/09/11(土) 03:10:01.40ID:w5S7rLqj
>>362
例えば>>3>>4にあるRust各book十数個のうちどれくらい読んでみましたか?
2021/09/11(土) 04:59:53.97ID:7r8uHUGr
ただのコード例ってのとは違うけどこれ読み進めるとかどうだろう
https://rust-unofficial.github.io/too-many-lists/index.html

Linked Listを色々頑張るやつ
2021/09/11(土) 05:21:08.84ID:w5S7rLqj
>>365
それはあまりにも偏った特殊ケースであることと
初心者向けではないということと
その件だとむしろ標準ライブラリとして提供されているリンクリストや双方向キューを覚えた方が実用的かなーhttps://doc.rust-lang.org/std/collections/
367デフォルトの名無しさん
垢版 |
2021/09/11(土) 17:59:37.96ID:iQv7wiiS
>>349
なるほど
2021/09/11(土) 21:06:20.65ID:KPnRgCeh
Rustは可読性をもう少し良くできなかったのかな
後発なのにJavaより読みにくいってのは問題だろ
2021/09/11(土) 21:16:46.98ID:PRM8i6LA
>>368
どのあたりが?
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
正当なスタイルが分かった上で競技としての割り切り方も分かっているなら問題ないんだけど、
競技から学ぶと変な癖が付きやすいというのは私も感じるなぁ。
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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