X



Rust part8

■ このスレッドは過去ログ倉庫に格納されています
0450デフォルトの名無しさん
垢版 |
2020/04/27(月) 09:24:11.80ID:xj40wisa
rustいつのまにか蟹のイメージになってるけど、オライリーの影響?それとももっと前から何かあるのかな?
0452デフォルトの名無しさん
垢版 |
2020/04/27(月) 12:48:32.95ID:vsE9eV5m
let mut heap = BinaryHeap::new();
heap.push(10);
heap.push(9);
heap.push(20);
for x in &heap {
println!("{:?}", x);
}

これでバイナリヒープすると
20
9
10
ってなるんだけどバグ?
0453デフォルトの名無しさん
垢版 |
2020/04/27(月) 12:51:07.20ID:On5R6UtW
>>448
配列のIntoIteratorは
&[T; N]と&mut [T; N]に対して実装されてるが[T; N]に対しては実装されてないのでmove不可

対してVecのIntoIteratorは
&Vec<T>と&mut Vec<T>だけでなくVec<T>に対しても実装されてるので
moveが必要なコンテキストならIntoIterator for Vec<T>が選択されmove可能
0456デフォルトの名無しさん
垢版 |
2020/04/27(月) 14:12:45.55ID:ZRv/ULjO
学術の巨大掲示板群 - アルファ・ラボ
ttp://x0000.net

数学 物理学 化学 生物学 天文学 地理地学
IT 電子 工学 言語学 国語 方言 など

PS 連続と離散を統一した!
ttp://x0000.net/topic.aspx?id=3709-0
0457デフォルトの名無しさん
垢版 |
2020/04/27(月) 15:43:57.57ID:vsE9eV5m
>>454
thx 見逃してた
0460デフォルトの名無しさん
垢版 |
2020/04/27(月) 22:17:40.40ID:e7WQ8CRR
>>457
型制約見ればええんやで。

`pub fn iter(&self) -> Iter<T>`は`impl<T> BinaryHeap<T>`。

`impl<T> BinaryHeap<T> where T: Ord,` に`pub fn into_sorted_vec(self) -> Vec<T>`てあるやろ。
rustのOrdは全順序や!
0461デフォルトの名無しさん
垢版 |
2020/04/28(火) 01:18:27.68ID:barKq4nx
この場合はifを使うのとmatchを使うのとどっちがおすすめ?

if nanika_shori().filter(hoshiimonokana).is_some() {
hoge();
mitsukatta();
} else {
fuga();
mitsukaranakatta();
}

match nanika_shori() {
Some(butsu) if hoshiimonokana(butsu) => {
hoge();
mitsukatta();
}
_ => {
fuga();
mitsukaranakatta();
}
}
0462デフォルトの名無しさん
垢版 |
2020/04/28(火) 01:37:40.02ID:aaB86vh6
>>461
後者は関数型言語風ってだけでしょ
関数型言語で is_some() にあたる関数は存在しなかったり、有るけど使うなって扱いだったりする
0463デフォルトの名無しさん
垢版 |
2020/04/28(火) 02:09:21.04ID:nfkWT3p7
テレワーク中なのか連休入ったせいなのか知らんけど猛者が全部回答してくれるから助かるわ
0464デフォルトの名無しさん
垢版 |
2020/04/28(火) 07:51:49.83ID:SJTliuFD
>>461
前者
0465デフォルトの名無しさん
垢版 |
2020/04/28(火) 11:46:15.82ID:nnss28av
>>461
match nanika_shori().filter(hoshiimonokana) {
Some(x) => {…},
None => {…}
}

if let Some(x) = nanika_shori().filter(hoshiimononanoka) {…} else {…}

boolを返す関数作ってif else
fn are_aruka(hoshiimono: Hoge) -> bool {
match nanika_shori() {
Some(x) if x == hoshiimono => true,
_ => false
}
}
0466デフォルトの名無しさん
垢版 |
2020/04/28(火) 12:32:50.40ID:GQyYGa/W
filter(...).is_some()
って形はかなり読みにくい
ようは設計が悪い
0469デフォルトの名無しさん
垢版 |
2020/04/29(水) 20:08:03.11ID:lsvcqJYy
Rustやる前に軽くScalaとかHaskellやっとけば
コレクションライブラリ見たときに「あっ、これ進研ゼミでやったところだ!」って
なるから理解が早いよ
0475デフォルトの名無しさん
垢版 |
2020/05/01(金) 10:58:05.97ID:gc2qK0CV
>>471
酷いAPI
stdがどうなってるかぐらい見たほうがいい
0476デフォルトの名無しさん
垢版 |
2020/05/01(金) 12:59:00.58ID:wrmDV0oq
Rustは、Releaseモードでも、Runtimeをstatic linkする場合は、61MB、
dynamic linkする場合は、8.2MBになるらしい。
dynamic linkで、さらにサイズ重視最適化した場合、4.6MB、strip した場合、
3.1MBになる。
でも、C++に変わる言語を標榜するにしては大きすぎる。

https://www.quora.com/Why-are-the-Rust-and-Go-binaries-so-large-compared-to-C-or-Pascal
0477デフォルトの名無しさん
垢版 |
2020/05/01(金) 13:58:13.26ID:xXuuls7c
>>476
>Rustは、Releaseモードでも、Runtimeをstatic linkする場合は、61MB、
>dynamic linkする場合は、8.2MBになるらしい。

Debugモードが61MB
Releaseモード(デフォルト設定)が8.2MB って書いてるよ
それにlinkするのはRuntimeではない
もう少しちゃんと読もう
0478デフォルトの名無しさん
垢版 |
2020/05/01(金) 13:58:40.83ID:i4mzH/oB
>>476
デフォルトでサイズが大きいという結論は間違ってないけど
もうちょっと英語ちゃんと読んだ方がいいと思う…。
あとその回答には書いてないけど、頑張ればCにサイズで勝つことは可能だったはず。
0479デフォルトの名無しさん
垢版 |
2020/05/01(金) 20:43:43.74ID:suCtdez/
>>476
Cで書いたプログラムが小さいのは標準ライブラリを利用しているから、だったと思うんだけど違った?
rustはmallocも自身に含めてたはずだし、Cの標準ライブラリ使うならもっと小さくなるはず

って>>476のQuoraの回答にちゃんと書いてあるじゃん!Cで15kb、Rustで14kbって!
自分でリンク貼るならちゃんと読め!もう!
0481デフォルトの名無しさん
垢版 |
2020/05/02(土) 00:00:07.90ID:rieFiUeI
release profileでもデバッグシンボル含めてるからprofileオプション安定化までお預けかな。
0484デフォルトの名無しさん
垢版 |
2020/05/02(土) 10:05:59.92ID:8Sc54whm
お前らおっぱいだって大きいほうが好きなくせに何バイナリのファイルサイズが大きめだからって文句言ってるんだよ
0488デフォルトの名無しさん
垢版 |
2020/05/02(土) 15:10:30.93ID:f7vdsp57
let hoge = match s {
  "hage" => hage,
  "moge"=> moge, // 何かの関数や構造体を返そうとしたがhogeは一意の型しか受け取らないから無理
  _=> return
}
loop {
  hoge()
}

的な事やろうと色々試したけど、超絶複雑な事になってヤバい匂いしかしない。
ループの外でループ内で呼ぶ関数の分岐を書くのは何かのアンチパターンなのか
そもそも、ループの中でMatch書いても外からイミュータブルな値を渡すの分かってるなら
コンパイラが最適化してループ毎に分岐なんてしないから普通に入れて書けば良い?
0489デフォルトの名無しさん
垢版 |
2020/05/02(土) 16:28:13.09ID:0Y98m9EQ
>>482
inclusiveなtake_untilは標準では無いみたいだから自分で作るかcrate探すかになるっぽい

https://play.rust-lang.org/?version=stable&;mode=debug&edition=2018&gist=b74ec6655adc38e1e790a35485eee01c
https://github.com/rust-lang/rust/issues/62208

既存Traitを拡張するのはめんどくさいから
自分ならイテレータを受け取ってイテレータを返す関数で我慢する
0490デフォルトの名無しさん
垢版 |
2020/05/02(土) 16:54:44.18ID:4YXjnjKT
>>488
hoge用にhageかmogeをとれるenumを定義すれば型は一意に定まる。
別にループ内でmatchしても分岐予測はほぼ当たるだろうし
性能的に問題はないと思うけど。
0491デフォルトの名無しさん
垢版 |
2020/05/02(土) 16:58:06.87ID:4YXjnjKT
あるいはFnとかにして型を揃えれば
loop内の分岐はなくなるかな。
たださっきも書いた通り分岐をなくすことに
それほど意味があるとも思えない。
0493デフォルトの名無しさん
垢版 |
2020/05/03(日) 14:40:33.37ID:CQw0w+cb
>>488
enumで紐つけても結局hogeでmatch使う事になる。
Fnで返すと所謂if文と関数ポインタどっちが早い?的な事になって
最適化するとif文のが早くなる。つまりループの中でMatchしとけば良い。
0494デフォルトの名無しさん
垢版 |
2020/05/03(日) 21:48:29.60ID:zX3s2fU5
rustのenumはsum typeだからjitがあればmegamorphicでもtracingじゃなくてもjit効いて
インラインキャッシュも必要ないからそのままインライン展開出来るんだが、この辺がAOTの限界だな。
まあ、分岐予測外れるような呼び出しなら初めからvtable使うだろう。

Rust/WinRT見てc++と違っていきなりマクロ出てくるからMFCの悪夢が蘇った。
0495デフォルトの名無しさん
垢版 |
2020/05/03(日) 22:46:23.02ID:zpY+Khfl
>>492
ローカルにあるcrateとrustのソースをgrepしてみたがほとんど使われてないね

シグニチャに書くことで可読性が高まるケースであれば使えばいいと思うけど
そうじゃなければ一旦受けてから関数内で分割したほうがよさそう
0496デフォルトの名無しさん
垢版 |
2020/05/04(月) 11:52:28.65ID:sauq4xLT
レンジ自体にマッチしたいんだけど書きかたって今はない?
match 1..3 {
2..3 => println!("2..3"),
1...3 => println!("matched!"),
_ => println!("_"),
}
0497デフォルトの名無しさん
垢版 |
2020/05/04(月) 12:22:11.14ID:au6sJ5VU
>>496
use std::ops::Range;

match 1..3 {
Range{start: 2, end: 3} => println!("2..3"),
Range{start: 1, end: 3} => println!("matched!"),
_ => println!("_"),
}
0498デフォルトの名無しさん
垢版 |
2020/05/05(火) 02:10:07.89ID:em9v0/Ay
>>497
ありがとう。
でもなんで
match 1 {
1...2 => println!("matched!"),
_ => todo!(),
}
こっちのマッチは ... で一個点々多く使わないといけなくなったの?
Range{start: 2, end: 3}をつかうなら1...2じゃなくて1..2でもよかったんじゃ
0500デフォルトの名無しさん
垢版 |
2020/05/05(火) 09:01:40.68ID:uTsiWylk
>>498
matchのarmでrangeを使うケースはほぼ100%inclusive rangeなので
half openのexclusive rangeとは区別して利便性を上げつつ
不用意なバグをコンパイル時に弾けるようにしたのが理由だと思うよ

>Range{start: 2, end: 3}をつかうなら1...2じゃなくて1..2でもよかったんじゃ
んん?
そもそも「レンジ自体にマッチしたい」ってどういう用途?
0501デフォルトの名無しさん
垢版 |
2020/05/06(水) 11:12:57.23ID:exILxtx0
Rust の API についてはメソッドのシグネチャとコメントからドキュメントを生成できるけど、
バイナリクレートにユーザー向けのドキュメントを付けるときの作法とかってあるの?
0504デフォルトの名無しさん
垢版 |
2020/05/07(木) 16:40:36.21ID:82eQknS5
ドキュメントコメントでのassetでのテストとmod testsってどう使い分けたらいいの?

ドキュメントテストすればユニットテスト書かなくていい?
ドキュメントは使用例だけで、assertでのテストって意味なくね?って思ってしまう。無視もできるし
0505デフォルトの名無しさん
垢版 |
2020/05/07(木) 17:28:34.50ID:k47Mu4KT
>>504
ドキュメントテストはドキュメントであってテストではない。
説明上分かりやすいならassertしてもいいけど、別になくてもいい。
それでもドキュメントテストを通すのは、古いサンプルコードがいつの間にかコンパイル通らなくなっている、というのを防ぐため。
ユニットテストは普通にmod testsで書けばいいよ。
0506デフォルトの名無しさん
垢版 |
2020/05/07(木) 18:37:23.38ID:ywncHnjy
doit()はclone()が入るとエラーが出るんだけど何で?
TにCloneが必要って出て来るけどTの実体をCloneしないのに必要ないだろJKって感じのエラーなんだが?
これどうしたらいいの?

https://play.rust-lang.org/?version=stable&;mode=debug&edition=2018&gist=31635004c1ad9fd9e5ba0f859f28ceb0
0507デフォルトの名無しさん
垢版 |
2020/05/07(木) 19:32:09.83ID:ywncHnjy
>>506
derive使うのやめて自分でClone実装したわ
deriveのCloneがおバカということがわかっただけ収穫とするわ
0508デフォルトの名無しさん
垢版 |
2020/05/07(木) 19:52:47.71ID:ywncHnjy
これdoit()のget()がTに'static必要ってコンパイル失敗すんだけど
Tを直接扱ってないんだからTに'static要らんだろって感じなんだが?
関数ポインタくらい静的に解決できんだろJK
どうしたらいいんだよ
https://play.rust-lang.org/?version=stable&;mode=debug&edition=2018&gist=b69fe063a3cc2fae6f1cc7536007fe8e
0509デフォルトの名無しさん
垢版 |
2020/05/07(木) 21:47:17.14ID:82eQknS5
>>505
てことはドキュメントで書いたコードは普通のコンパイルエラー検知しなくてassertのエラーだけ検知するの?
なんかそれはそれでやばくないか
0510デフォルトの名無しさん
垢版 |
2020/05/07(木) 21:48:25.25ID:TSVqZJLC
コンパイル通さずにどうやってassertだけ通すんじゃ
0512デフォルトの名無しさん
垢版 |
2020/05/07(木) 23:07:35.28ID:k47Mu4KT
>>509
いやいや、コンパイルエラーは検知したくてassertはどっちでもいいって話。
コンパイルできないサンプルコードを検出したいんだから。
0513デフォルトの名無しさん
垢版 |
2020/05/08(金) 15:31:13.15ID:2R+BCvOe
なんで型って大文字始まりなのにi32とかは全部小文字始まりになってんの?
初期のデザインミス?
0516デフォルトの名無しさん
垢版 |
2020/05/09(土) 06:11:48.26ID:gxFlq1V3
Rustみたいに標準ライブラリは最小に留めてるような言語って他にありますか?

それとコンパイラ内部のCargo.tomlにライブラリのバージョン書けば別に最小に留めなくてもと思うんですが、どうでしょうか?
0519デフォルトの名無しさん
垢版 |
2020/05/12(火) 08:44:05.53ID:l1cRSbJI
これってなんで&mut になんの?
n: mut &i32のほうが差分的にも視覚的にもいいと思うけど、どっかに理由とか書かれてないかな?
fn example(n: &mut i32) {
}
let mut r = &10;
example(mut r);
0521デフォルトの名無しさん
垢版 |
2020/05/12(火) 11:12:17.10ID:rr7jvTFY
>>519
変数がmutableなのか、immutableなのかと
変数の型がownedなのか、shared referenceなのか、mutable referenceなのかとは別

mutable referenceを表す記号として`&mut`で一塊なのでmut &i32は微妙
n: mut i32みたいに型として意味のないコードを書いて
何が悪いのかわからないってことになりにくい

コンパイラ的にも`&`が先にあったほうが処理が簡単そう
0522デフォルトの名無しさん
垢版 |
2020/05/12(火) 17:14:57.85ID:pSulPVQF
なるほど
0523デフォルトの名無しさん
垢版 |
2020/05/12(火) 17:49:29.28ID:jco3JkFf
>>521
微妙というかmut &i32だとimmutableなi32へのmutableな参照になるから意味が違うのでは?
もとのi32は変更不可だが別の参照を再bindは可能という。
0524デフォルトの名無しさん
垢版 |
2020/05/12(火) 18:24:06.26ID:rr7jvTFY
>>523
変数のmutabilityと変数の型をごっちゃにしてない?

`let x: &mut i32`と書くところを
`let x: mut &i32`と書くような文法にしたほうがよかったのでは
ってのが>>519の意見
0525デフォルトの名無しさん
垢版 |
2020/05/12(火) 19:18:36.86ID:j2+Ql/jy
>>524
その場合、今の文法でmut &i32と書くケースはどうすべきなの?
そこだけ変えちゃうと、全体的に整合性が取れなくなるのではないかと思うけど。
0526デフォルトの名無しさん
垢版 |
2020/05/12(火) 21:20:08.42ID:rr7jvTFY
>>525
今の文法でmut &i32と書くケースは無いよね?

`let x: &mut &i32`って書くべきケースのことなら
`let x: mut &&i32`になるんじゃない?
0527デフォルトの名無しさん
垢版 |
2020/05/12(火) 21:34:24.99ID:FmqTBss/
>>526
確かに勘違いしてた。今の文法だとmut x: &i32だった。
なので今は
x: &mut i32
mut x: &i32

x: mut &i32
mut x: &i32
にしても別に問題はないのか。なんとなく両者の区別はしにくくなってる気はするけど。
0528デフォルトの名無しさん
垢版 |
2020/05/12(火) 21:45:24.39ID:l1cRSbJI
>>521
パース負荷はおいておいて、mut i32ってかいてあったら普通にコンパイルエラーでよくないか?
エラーの親切さはRustの特徴だし。
mut 書いてる時点で参照なのは当然なんだから書き忘れってすぐわかるじゃん
それに語彙的にmutable referenceとも一致して自然だから前から疑問だった

>>526 のパターンとかも今までの書き方だとかなり読みにくいよね
0529デフォルトの名無しさん
垢版 |
2020/05/12(火) 22:06:14.36ID:rr7jvTFY
本当の理由は知らないけど、その区別しにくくなるってところがポイントだったんじゃないのかな

mut i32はコンパイルエラーだろうけど、今はエラーメッセージ見ても
&mutがあれば型、mutがあれば変数のmutabilityって詳細読まなくてもすぐ分かる

慣れかもしれんが俺は今の文法のほうが読みやすいと感じる
let mut x: &mut &i32
let mut x: mut &&i32

let mut x: &mut &mut i32
let mut x: mut mut &&i32
0531デフォルトの名無しさん
垢版 |
2020/05/12(火) 22:36:30.89ID:RlXY9TUm
>>530
使いたくなくてもネットワーク使うcrateがtokioにべったり依存してて
非同期にこだわる意味ないアプリでも使わざるを得なくなるのがRustのダメなとこ
0533デフォルトの名無しさん
垢版 |
2020/05/13(水) 01:28:10.47ID:IZIPIE/9
非同期に拘らないならstd::net使えばよくない
0534デフォルトの名無しさん
垢版 |
2020/05/13(水) 14:58:18.04ID:n4QRUOl7
今の主流は tokio か async-std だけど io-uring 対応でまた勢力図に変化が起きたりするのだろうか
0535デフォルトの名無しさん
垢版 |
2020/05/13(水) 22:46:58.63ID:0Q+bejh+
乗り遅れた。
tokioは使ってないけどデスクトップでnon-blocking file ioが欲しい。ブロックしたら並列の意味がない。

>>531
ランタイムと付いてくるapiで肥大化するのが問題なんだよね。
0537デフォルトの名無しさん
垢版 |
2020/05/14(木) 09:41:17.62ID:WpNijTVY
望まぬ非同期は一応 tokio::runtime::current_thread::block_on_all() で回避できるか
それでもビルドが一気に遅くなる
0539デフォルトの名無しさん
垢版 |
2020/05/14(木) 18:17:46.89ID:nGNfHuw+
なるほど
0540デフォルトの名無しさん
垢版 |
2020/05/14(木) 21:36:47.59ID:AoVs9mpY
日本のRust界隈で有用なRust関連のツイートしてる人教えて
0542デフォルトの名無しさん
垢版 |
2020/05/15(金) 09:40:19.45ID:OlE2WbGd
0543デフォルトの名無しさん
垢版 |
2020/05/16(土) 07:49:09.76ID:4fgNGNa5
io-uringと今までの非同期処理の違いってなに?
パフォーマンスそれほど変わるもんなの
0545デフォルトの名無しさん
垢版 |
2020/05/18(月) 04:57:51.24ID:z6Kgscbk
返り値に &'static str ってライフタイム指定ないといけないけど、推論だけで解決できない問題があるから書かないといけないの?
Stringからderefで生成した&strでも結局はIO以外で来たStringは'staticでしょ?推論できそうだけど
■ このスレッドは過去ログ倉庫に格納されています

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