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/04(土) 19:48:22.92ID:FwiYtexa
>>299
もちろんshellは関与していない。
環境変数PATHに従い直接起動。
>>301
どのプログラミング言語で書いていようが、外部コマンドの呼び出しは普通にある。
それをゼロにするかどうかは様々なコストの問題。
例えば、そこがボトルネックになったら内部化など。
2021/09/04(土) 20:41:42.28ID:HZGHSQTb
>>301
shell を作ってるんだから外部コマンド呼び出してなんぼだと思うんだが
304デフォルトの名無しさん
垢版 |
2021/09/04(土) 21:53:33.09ID:CUdge0sZ
>>303
>>294 はシェルを自作してるの?
2021/09/04(土) 22:09:11.34ID:HZGHSQTb
>>304
自作のbashコマンドを自作の bash 互換シェルと読んでコマンド置換の仕組みを作ろうとしてるのかと思ったけど
もしかして bash スクリプトで書いたコマンドのことだったりする?
それにしたって外部コマンド含めて自作する必要はないと思うが
2021/09/04(土) 23:54:37.12ID:iqtSb51S
なるほど
>>296と書くのではRustで書き直したことになっていないとはそういう意味か
これでいいのかな
use locale::Time;
use chrono::{Local, Datelike};
let s = format!("今日は{}曜日です", Time::load_user_locale().unwrap().short_day_name(Local::now().date().weekday().num_days_from_sunday() as usize));
2021/09/05(日) 01:20:41.47ID:lJqHVJAL
$ foo=$(bar $(baz))

let foo = bar(baz())
308デフォルトの名無しさん
垢版 |
2021/09/05(日) 14:42:42.92ID:5vCe2TIK
>>294
>rustの勉強のため自作のbashコマンドを、rustで書き直し
https://github.com/uutils/coreutils/blob/master/src/uu/echo/src/echo.rs

> コマンド置換( $(echo ) )はどうやればいいでしょうか?
https://www.joshmcguigan.com/blog/build-your-own-shell-rust/
https://zenn.dev/garebare/articles/a463257c447fa9

独自shellスクリプトをbashやzshのように実行する際は標準入力を逐次読むインタラクティブシェルの
動作モードの他に第一引数のスクリプトパスを受け取り連続的に動作するようにしなければなりません。
上記のサンプルのように変数やコマンド置換を展開(子プロを作って実行結果を保持する)パーサーが
必要になります。(上の例ではリダイレクトやパイプなどしか処理していませんが)またファイル先頭の
#!/bin/shと同じようにshebangを認識するのはOSが行います。
そのほかにもifに使われるや"["もしくはtestなどは大昔はコマンドでしたが、現在は多くのシェルでは
組み込みのビルトインコマンドになっています。
また現在でもbashなどでクラッシュさせる脆弱性が発見されていますが、GNU bashの場合はパーサーは
手書きではなく、parse.yなどのyaccです
2021/09/05(日) 19:37:48.09ID:vqQF7q4/
シェル自体をRustで実装する話なん?
2021/09/05(日) 20:23:09.21ID:qXYO1Gcj
想定外。
シェルスクリプトで書かれてる日常ツール類を、高速化&練習ついでにRust化、ってのはよくある話なので、今回もそういうことかと想定してた。
311デフォルトの名無しさん
垢版 |
2021/09/05(日) 20:31:50.21ID:Mq9n6pyZ
grepの書き換えとか入門用テキストあるあるだしな俺もそれかと思ってたw

インタープリターみたいの作りたいなら単純に考えて$(.+)みたいの発見し次第rustで書かれたプログラムに書き換え
この際$(.+)の.+の部分にもrust書き換えプログラムを同様に適用のrecursiveな奴考えるな
match等でregex構文が扱いやすい分rust native interpreterみたいの造りやすそう
あとそうゆうのredosだかなんだかのrust os projectみたいのあるから見たら面白いんじゃね(´・ω・`)
2021/09/07(火) 12:42:27.81ID:O1QkM6d3
nullの可能性がある複数の参照を作りたい場合って
OptionとかRcを組み合わせるの?
縦によも横にもコードが長くなりそう
2021/09/07(火) 13:22:01.93ID:J2y4//gF
Option<&T> や &Option<T>でも良いかも知れないけど状況次第
可変参照にしたいなら Rc<RefCell<Option<T>>> とかになるかも
2021/09/07(火) 14:39:19.62ID:vfOWvkqv
Rustの文化詳しくないけど、null objectは使わないの?
せっかく静的安全性にこだわっているのに、型無しのnullを使うのはこだわりが足りない気がするなぁ。
2021/09/07(火) 15:00:30.72ID:gb4OeP+0
OptionがあるのにNullObjectいらなくないです?
2021/09/07(火) 15:16:47.38ID:yn0D/zff
>>314
見当違い。 >>312 はどこも指さない参照を便宜的に null と言ってるだけで、
実際には代数的データ型を活用して区別しようとしている。
2021/09/07(火) 15:20:59.00ID:oZHnA/lF
NullObjectは時代遅れ過ぎる
318312
垢版 |
2021/09/07(火) 15:36:48.61ID:O1QkM6d3
>>316
正解

ただし、Rc<RefCell<Option<T>>>とか見ちゃうと
生ポインタにしたくなってくる……
2021/09/07(火) 15:42:12.42ID:gb4OeP+0
参照をRcするような場面てあんまりないような気がする

ところでRc<RefCell<Option<T>>>は、
参照じゃなくてヒープにある(かもしれない)Tの共有になりませんか
2021/09/07(火) 15:58:38.34ID:X4ha4H+D
>>319
実体は必ずヒープ上
実体の構造は(強,弱,(借,(Some,T))
そしてそのヒープ上にある実体を指してるポインタはどこにあっても複数あってもよい
2021/09/07(火) 18:22:59.95ID:J2y4//gF
>>319
ヒープ上にある RefCell<Option<T>> を共有することになるね
参照 (&T) ではないというのはそう
2021/09/07(火) 19:09:15.95ID:/9ekKyA5
>>316 >>318
サンクス。JavaのOptionalみたいなものね。

>>317
nullobjectと比較したときのメリットは?
条件分岐を強制させることができることくらいかしらん?
2021/09/07(火) 20:06:06.42ID:Z/GuZfd2
>>322
impl<T> SomeTrait for Option<T> where T: SomeTrait { ... }
ってやれば条件分岐すら自分で書かなくていいよ
2021/09/07(火) 21:28:45.74ID:GNL8Ud6q
>>323
それはTraitのメソッドで分岐相当のコードを書くか
chainさせるだけで分岐処理を遅延するかのどちらかなので
分岐すら自分で書かなくていいというのはちょっと違う気がする
325デフォルトの名無しさん
垢版 |
2021/09/07(火) 22:29:28.46ID:KSe0arFM
本来はOption/Result/(Either)はRust言語的な仕組みでは無く、ライブラリの作法に過ぎないが、ランタイムが
無いはずなのに、Resultなどで宣言しているところで原則として捕捉しないpanicがあるのは納得できない人は
結構いると思う。言語の構文でmatchや?など、まさにそれのサポート構文があるのに、unwrapしたらpanicで
この話は嫌がる人が結構いるけど、OptionもResultもPanicも取っ払った最小の標準ライブラリが欲しい
2021/09/07(火) 22:45:10.91ID:rBwLSogt
>>325
何が言いたいのか分からん
2021/09/07(火) 23:03:38.48ID:2A/XDTjQ
>>325
そこは使い分け。
エラーな時にそのままエラー吐かせても構わない場合は、main()をResult型にしてしまうし、
きちんとエラー処理する必要あるものな場合は、少なくともmain()やそれより下でmatchでResultを必ず受け止める。
2021/09/07(火) 23:11:59.18ID:oZHnA/lF
>>322
比較すべきものではない
ヌルオブジェクトはインターフェースで型を隠蔽する手法
一方Optionは型をラップすることでエラーを明示する手法
似てるようで根本が違う
2021/09/07(火) 23:18:49.53ID:2A/XDTjQ
あと後者の場合、unwrap()も基本的には使わない。
例外的に使うのはフィルタし終えて必ずSome(T)となっているものを剥がす時だけ。
つまりpanicはさせないので、その>>325の懸念事項は発生しない。
2021/09/08(水) 07:19:42.43ID:yXT40j/x
素人です、質問させてください
Rustでスマホアプリやwebアプリは作れますか?
作れるとしたら
java/kotlinやswiftやjavascriptより作りやすいですか?
アプリ制作でこれらの言語よりRustは優れてますか?
2021/09/08(水) 07:34:28.50ID:bql1CtjZ
Rust+JavaScriptでウェブアプリとそのためのサーバーサイドは作れる
ウェブブラウザ上ではJavaScriptが必須なのでRustだけにはできない
ただしウェブブラウザ上ではJavaScriptに加えてWebAssembly(Wasm)も動いてこれはRustで書いたプログラムが動く
なのでJavaScript部分を最小限にしてRustで書いたWasmがメインというケースもないわけではない
サーバーサイドはRustだけで全て構築できる
2021/09/08(水) 07:48:35.45ID:yXT40j/x
ありがとうございました
スマホアプリを作るならKotlinやswiftってことなんですね
大変に参考になりました。ありがとうございました。
2021/09/08(水) 08:09:19.60ID:nCYYHiA4
オマケみたいなもんやな
2021/09/08(水) 08:14:48.98ID:bql1CtjZ
>>332
そんなことはない
スマホアプリならKotlinとSwiftの2種類を無駄に覚えずともJavaScriptだけで両OS向けスマホアプリ作成が可能
もちろんスマホでもウェブアプリが動きアプリの種類によってはウェブアプリで十分なためスマホアプリを作らないケースも出ている

一方でRustで書いてAndroid上でツワモノもいるがそれはおいとくとして
Rustをこの件で使うケースはウェブブラウザで動くWasmのプログラミングする時かサーバーサイド側
あとはGoogleがAndroid OS開発にRustを使い始めた
2021/09/08(水) 14:35:34.40ID:kw5H9VGz
めっちゃWasm使ってるわ、使い心地としてはgoのが良いのだが
てか絶対JS書きたくない勢以外は勧められないけどな
エントリーポイントで4〜5行JS書かざるを得ないが、そこはコピペだから俺は1行も書いてない
336デフォルトの名無しさん
垢版 |
2021/09/08(水) 19:04:28.13ID:beXhRlkk
>>335
javascriptからwasmにディスパッチする際のオーバーヘッドってどう?
2021/09/08(水) 19:45:38.33ID:tR72XlKG
getopt()みたいなのでRust標準はどのクレイト?
2021/09/08(水) 20:27:20.45ID:aH1RnViv
clapだけど、それを使ったさらに便利なstructoptのほうがおすすめかも
2021/09/08(水) 21:24:09.27ID:Ug8WkgwI
clapはv3でstructoptの機能を取り込むから、今ならclapの3.0.0-beta4を使うのでもいいかも
2021/09/08(水) 21:44:07.80ID:XbOUeFJA
>>339
その後、structoptはどうなるの?
2021/09/08(水) 23:46:53.75ID:tR72XlKG
>>339
なるほど
v2のビルダー方式に加えて
v3でマクロ多用で見やすく書きやすくすっきりしたという感じ?
2021/09/09(木) 00:04:52.59ID:fa/WJTRs
マクロは見やすさだけじゃなくてコンパイル時に諸々チェックされるのが嬉しい
2021/09/09(木) 20:16:33.24ID:Rwhy6P/q
数値の並びがある時に
その中の一番大きなものがある場所(index)が欲しいのですが
Rustではどう書くとよいでしょうか?
2021/09/09(木) 20:38:00.34ID:fa/WJTRs
>>343
たとえばこう
https://play.rust-lang.org/?version=stable&;mode=debug&edition=2018&gist=c7a0d0459c540d7b373b124d7faf239a
2021/09/09(木) 21:09:46.20ID:18O2MBOf
>>344
copied()っているっけ?
2021/09/09(木) 21:32:28.08ID:Rwhy6P/q
ありがとうございます
無しでもいけました

別の質問です
Vecにスライス(の各値のコピー)をappendしたいのですが
append()メソッドはVecしか引数に取れず困っています
どうすればいいでしょうか?
2021/09/09(木) 21:36:39.36ID:dEhWYfPh
ちったあググれよ
教えて君は嫌われるよ
2021/09/09(木) 21:55:23.66ID:aKI9+8DZ
>>346
https://doc.rust-lang.org/std/vec/struct.Vec.html
2021/09/09(木) 22:34:44.73ID:18O2MBOf
>>346
append()はその名前から想像しにくい実はムーブで引数側のVecは空になるw
じゃあappendはどうすればいいかというと
1つだけappendするpush()の複数版のpush_all()が元々あって
それは名前変更で今はextend_from_slice()になった
がその中身はより一般化したExtendトレイトのextend()を呼んでるだけになったので
結論としてはv.extend(&a)が正解
2021/09/09(木) 23:25:03.49ID:12Nq5czF
Rust 1.55.0 リリース
2021/09/10(金) 01:12:44.66ID:t0Gbnfvj
faqのような気がするんだが、以下のようなコードって
どうすればコンパイル通る?

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

fn main(){
let ar = [St{s: String::from("str")}; 10];
}
2021/09/10(金) 01:34:46.88ID:Dnq/g++J
参照を配列に格納するか
let st = St{s: String::from("str")};
let array = [&st; 10];

Stringじゃなく&strにするか
#[derive (Debug, Clone, Copy)]
struct St{
s: &'static str
}

かな?
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() したくない
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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