Rust part9

■ このスレッドは過去ログ倉庫に格納されています
2020/08/23(日) 01:07:35.52ID:MgEpWwVh
Mozilla発のRust言語のスレ

公式
https://www.rust-lang.org/
https://blog.rust-lang.org/
https://github.com/rust-lang/rust

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

前スレ
Rust part8
https://mevius.5ch.net/test/read.cgi/tech/1579834072/
2020/10/12(月) 17:06:26.06ID:tosLr/AM
>>264
>let &mut a=&v[0];

let a = &mut v[0];
2020/10/12(月) 19:19:30.09ID:Z3Kcjb2S
>>267
ありがとうございます。

>>268
なるほど言われてみれば文法的にそうでないと駄目でした。
しまった。
270デフォルトの名無しさん
垢版 |
2020/10/12(月) 19:50:22.11ID:ldeP4Qys
https://play.rust-lang.org/?version=stable&;mode=debug&edition=2018&gist=a388e403b6cd7afe902a9fd8618b5a65

質問内容とブレてたらごめんなさい
2020/10/12(月) 19:53:01.17ID:P0Nqqpd2
TがCopyだと let &mut a = &mut v[0]; ならコンパイル通っちゃうのは落とし穴かもしれない
2020/10/12(月) 19:54:11.97ID:P0Nqqpd2
>>270
get_mutをunwrapしちゃうなら普通に &mut v[0] で良いと思う
2020/10/20(火) 10:25:29.99ID:ohigEgI0
Rustは2番目にエネルギー効率の良い言語
https://okuranagaimo.blogspot.com/2020/10/blog-post_19.html
2020/10/20(火) 12:34:59.11ID:MZbW1JAa
アセンブラ使えないやつがいるとは。
2020/10/20(火) 19:00:44.91ID:CHq3Beyq
勉強始めたばかりですが変数のシャドーイングって必要ですか?

なんとなくグローバルに置いた変数もシャドーイングできそうなのですが実害は出たことありますか?
多分ないと思いますが…
2020/10/20(火) 19:31:52.86ID:KPdri9BA
Which Programming Languages Use the Least Electricity?
https://thenewstack.io/which-programming-languages-use-the-least-electricity/
> Energy consumed Run-time
> C 57J 2019 ms
> Rust 59J 2103 ms
> C++ 77J 3155 ms
> Ada 98J 3740 ms
> Java 114J 3821 ms
2020/10/20(火) 20:46:27.74ID:7hmMXh1W
デバッグやバグ修正に必要なエネルギーコストを加味したらCより効率よくなりそう
2020/10/21(水) 02:18:21.88ID:Q9+kxPSM
Rustはビルドでめっちゃ電力使うやろ
2020/11/01(日) 07:27:17.14ID:an3UASXf
let mut bt = (0..10).collect::<BTreeSet<_>>();
for e in bt.iter() {

// ここで条件に一致する要素をbtから削除したい

}
こんな感じのものを作りたくなったのですがどうすればいいのでしょうか?

うまい具合にやる方法が思いつかなくて以下のようにやっているのですが、なんというかすごくアホくさいというか・・・

let mut bt = (0..10).collect::<BTreeSet<_>>();
let mut temp = Vec::new()
for e in bt.iter() {
if e == Foo { temp.push(e); } // 削除予定のものをtempに入れる
}
for e in temp {
bt.remove(&e);
}
2020/11/01(日) 11:33:15.11ID:lQA9Y5E+
let bt = (0..10).filter(|e| eが要るなら真).collect::<BtreeSet<_>>();
じゃあかんのか
2020/11/01(日) 13:38:40.42ID:an3UASXf
btがこの例のとおりのものならそれでいいんですけど、
いろんな状況でbtに要素が追加されるっていう感じです

あと、if e == Fooはちょっと雑すぎましたif is_xxx(e)とかのほうがよいです
2020/11/01(日) 17:37:39.36ID:o3MRCmTo
コンテナのイテレーターのループ回してる間にコンテナの要素を追加や削除は出来ない。これは他のコンテナ(Vecなど)でもそう。どうしてもやるなら内部実装を理解した上でunsafeな方法で。
「いろんな状況でbtに要素が追加される」がループ中なのか何なのか分からないのでどうしようもないが、
let bt = bt.into_iter().filter(|&e| e == foo).collect::<std::collections::BTreeSet<_>>();
で新たなbtを作るか、
もとのbtから要素を削除するにしても
for e in bt.iter().filter(|&&e| e == foo).cloned().collect::<Vec<_>>() {
bt.remove(&e);
}
などでもう少し簡潔に書ける。
2020/11/01(日) 18:31:04.97ID:adfXjKjb
BTreeSet::drain_filter が安定化されるのを待とう

std::collections の unatable な機能を含めて切り出した crate とかあれば良いのに
2020/11/01(日) 18:31:59.68ID:adfXjKjb
>>282
Vec::retain がある。
2020/11/01(日) 19:09:00.30ID:o3MRCmTo
retainやdrain_filterについて不勉強だった。ありがとう。
2020/11/06(金) 03:44:45.46ID:S3a0GE/K
Rust book 構造体の章の以下のコード片なんですが
let mut user1 = User {
email: String::from("someone@example.com"),
email: String::from("someusername123"),
active: true,
sign_in_count: 1,
}

user1.email = String::from("another@example.com");
//コード片ここまで

最後の行でどこからも参照されなくなった元の
String::from("someone@example.com")
は、どういう理屈で解放されるんでしょうか?
もしGC言語なら最後の行でGC対象になるとこですけど。
Rust bookのこれ以前の章で、変数がスコープを外れるときdropが呼ばれることの説明はあったのですが、変数の束縛外れちゃったStringはいつ、どこで?
2020/11/06(金) 04:09:10.53ID:2cok4roU
>>286
最後の行でdropされるのは同じ
初期化済みの変数に新しい値を束縛したら古い値はdropされる
2020/11/06(金) 04:35:01.60ID:B4UB4dMh
>>287
ありがとうございます。
変数にバインドされてるヒープ領域がdropされるのはその変数がスコープを抜ける}の時ですよね。
>>286
初期化済みの変数に新しい値を束縛してる
user1.email = String::from("another@example.com");
から、
スコープが閉じる}まで、元の
String::from("someone@example.com")
のヒープ領域は解放されないということでしょうか?
user1.email = String::from("another@example.com");
の直後に解放されるのではなく?
2020/11/06(金) 07:48:41.67ID:aWxirctc
>>288
https://doc.rust-lang.org/reference/destructors.html

> Assignment also runs the destructor of its left-hand operand, if it's initialized.

だそうです
290デフォルトの名無しさん
垢版 |
2020/11/06(金) 08:36:34.29ID:HarnCsHz
考えてみりゃ確かにunstableのcrateってめっちゃいい案だな
use unstable::prelude::*;
で全部取り込める上にバージョンあげたらunstableから無くなってstdの方が挿し代わって使われるし
2020/11/06(金) 08:47:23.44ID:mKCogF8p
明らかに可読性悪い言語なのだがあと5年くらいしたらこの界隈も気づくかもね
292デフォルトの名無しさん
垢版 |
2020/11/06(金) 08:54:20.60ID:wXTP989a
5年先いくパイセン降臨
2020/11/06(金) 09:52:32.90ID:S3a0GE/K
>>289
なるほど!分かりましたありがとう
2020/11/06(金) 11:09:54.01ID:ifaT2orV
可読性が悪い「言語」ってそうそうあるもんかね
2020/11/06(金) 11:22:47.79ID:JyOrEzG9
それ、「俺様には理解できない」にderefされてます
2020/11/06(金) 20:08:48.42ID:g6FZ2Lxp
>>291
esolangはさておきAPLとかは難読言語といっても良いかも
あとは暗黙の○○が多い言語や記号が多い言語は初心者にとっては難読だと思うけど
Rustはこれらには当てはまらないと思うけど、どういう点で難読と思ったのか教えて欲しい
297デフォルトの名無しさん
垢版 |
2020/11/11(水) 20:37:16.07ID:ZuM/CkEs
>>291
お前は5年後もC++使ってろよ
2020/11/12(木) 10:54:00.16ID:uK53dAw4
fn foo(bar: impl Buzz)
というシグネチャは、
fn foo<T: Buzz>(bar: T)
の構文糖なんですよね?

では、
fn foo() -> impl Buzz
を、
fn foo<T: Buzz>() -> T
と書けないのはなぜなんでしょう?
2020/11/12(木) 11:47:01.17ID:tcFc7SO9
>>298
>fn foo<T: Buzz>(bar: T)
>の構文糖なんですよね?

違う
2020/11/12(木) 12:00:24.36ID:tcFc7SO9
とりあえずココを読むといい
https://doc.rust-lang.org/edition-guide/rust-2018/trait-system/impl-trait-for-returning-complex-types-with-ease.html
2020/11/12(木) 13:24:24.86ID:uK53dAw4
>>299
Rust bookにはsyntax sugarと書かれていたのですが…
https://doc.rust-lang.org/book/ch10-02-traits.html#trait-bound-syntax
> The impl Trait syntax works for straightforward cases but is actually syntax sugar for a longer form, which is called a trait bound; it looks like this:

>>300
ありがとうございます。
Rust bookはあんまり信用できないのかな…
2020/11/12(木) 16:23:24.97ID:tcFc7SO9
>>301
マジか
どっちも書いてる人は同じだから
引数ポジションについては細かい違いはあってもシンタックスシュガーなのかも

ただ戻り値ポジションの場合は
ジェネリックでは書き直せないから確実に違う
303デフォルトの名無しさん
垢版 |
2020/11/12(木) 18:49:52.91ID:C+/hhwIt
記号が多い言語は英語の苦手な日本人には有利だ
英文に近づけようとする言語は不利だ
2020/11/13(金) 19:01:00.42ID:nD6TGu67
そんなあなたにPerlがあるよ
2020/11/13(金) 23:39:03.73ID:RhbFV+AU
APLもおるでよ
2020/11/14(土) 06:16:49.16ID:6dxHy4Fn
python最強じゃん
2020/11/14(土) 09:55:40.26ID:B7e1nuZg
LISPかな。まあ記号と言っても括弧ばっかりだが。
2020/11/14(土) 10:07:50.72ID:DnZAmAgg
「Lots of Isolated Silly Parentheses」の略だからな。
2020/11/14(土) 10:52:27.43ID:wQlu6eHI
>>300
読んでて知ったけど::<T>のことturbofishっていうんだ
かわいい
2020/11/14(土) 12:17:47.68ID:dRjRf4O1
わかる https://turbo.fish
2020/11/14(土) 13:14:02.66ID:DnZAmAgg
The name "turbofish" was made up by reddit user deadstone in 2015, and has since caught on in the Rust community, being used even in the official documentation.
「turbofish」という名前は、2015年にredditユーザーのdeadstone氏によって作成され、それ以来Rustコミュニティで定着し、公式ドキュメントでも使用されています。
312デフォルトの名無しさん
垢版 |
2020/11/15(日) 04:06:11.96ID:H90rIdiK
function<>()の方が良かったけどね。パーサーの複雑性があって解決されてなく、もうここまで広まったしいいやってなってるけど
2020/11/15(日) 23:56:20.08ID:HUIHtxgp
>>301,302
型制約と存在型じゃ概念が違うから構文糖は語弊がある。
生成するコードはどちらもモノモーフィックな関数吐くけど存在型は第一引数の違いだけでコンパイル時に
ディスパッチ先が一意に決まらないケースが有るからマルチメソッドを直接サポートしない弊害があるかな。
314デフォルトの名無しさん
垢版 |
2020/11/20(金) 21:14:37.50ID:YhokOqrJ
Rust 1.48リリース
2020/11/20(金) 21:23:36.45ID:g8U1YOSi
Internet Archive、Flashコンテンツをアーカイブ プラグインなしで21年以降も閲覧可能に
https://www.itmedia.co.jp/news/articles/2011/20/news143.html

プログラミング言語Rustで作られたFlashのエミュレータ「Ruffle」を使うことで、Flashプラグインをインストールしなくても、WebAssembyが動作するWebブラウザさえあれば動作するとしている。
2020/11/20(金) 23:10:09.72ID:znicv9zG
すげえなww
でも先人の苦労の作品が残ってよかった
2020/11/22(日) 16:39:30.67ID:ujQ9d+0r
Rust bookのDropトレイト解説のページ ( https://doc.rust-jp.rs/book-ja/ch15-03-drop.html ) で質問です。
以下のようなコードなのですが、

struct CustomSmartPointer {
data: String,
}

impl Drop for CustomSmartPointer {
fn drop(&mut self) {
println!("Dropping CustomSmartPointer with data `{}`!", self.data);
}
}

fn main() {
let c = CustomSmartPointer { data: String::from("my stuff") };
println!("CustomSmartPointers created.");
}

これ、dropの実装部分にprintln!しか書かれてませんが&self.dataの処理は書かなくてよいのでしょうか?
例えば、println!の下に、
drop(&self.data);
のように。
どちらかがコンパイルエラーになるならいいのですが、書いても書かなくてもどちらでも問題なくコンパイルが通ってしまい、困惑しています。
2020/11/22(日) 16:58:52.26ID:JIsF8Dpm
>>317
もう少し細かい話はこの辺に書いてあるよ。
https://doc.rust-lang.org/std/ops/trait.Drop.html

簡単に言えばそのdataは勝手に解放されるからdropは不要。
解放以外で何か処理したいなら書けばいい。
drop(&self.data)としたとしても、それは参照を作ってその参照を即座に破棄してるだけなので特に意味はない。
本当にdataを解放したいならdrop(self.data)になるけどこれはコンパイルエラーになるはず。
2020/11/22(日) 17:05:23.09ID:JIsF8Dpm
あ、最後の行のは多分deref抜けてるな。
いずれにしてもdropするなら所有権を取る必要があるけど、
&mut selfからdataの所有権を取る方法はないので
正しくdropするコードを書けばエラーになるはず。
2020/11/22(日) 17:16:38.55ID:ujQ9d+0r
>>318-319
おお、
drop(self.data);
でも
drop((*self).data);
でも同じ、
cannot move out of `self.data` which is behind a mutable reference
エラーでました!
スッキリしましたありがとうございます。
std::mem::dropの実装って
pub fn drop<T>(_x: T) { }
だったんですねぇ…
2020/11/24(火) 00:31:06.85ID:EBaS3Lgi
Rust bookのRefCell解説のページ ( https://doc.rust-jp.rs/book-ja/ch15-05-interior-mutability.html ) で質問です。
以下のようなコードなのですが、

pub trait Messenger {
fn send(&self, msg: &str);
}

pub struct LimitTracker<'a, T: 'a + Messenger> {
messenger: &'a T,
value: usize,
max: usize,
}

impl<'a, T> LimitTracker<'a, T>
where T: Messenger {
pub fn new(messenger: &T, max: usize) -> LimitTracker<T> {
LimitTracker {
messenger,
value: 0,
max,
}
}
// 以下略

pub struct LimitTracker<'a, T: 'a + Messenger> {
の行でトレイト境界に
'a + Messenger
を指定しているようなのですが、
このような書き方今までに出てこなかったので試しに
pub struct LimitTracker<'a, T: Messenger> {
と書き替えてみたところ、警告もなしにコンパイルできてしまいました…
これ、何の意味があるんでしょう?
2020/11/24(火) 01:32:20.18ID:mGIqKDo2
>>321
とりあえず最新のThe Bookを見たほうがいいんでない?
https://doc.rust-lang.org/book/ch15-05-interior-mutability.html

https://doc.rust-lang.org/edition-guide/rust-2018/ownership-and-lifetimes/inference-in-structs.html
2020/11/24(火) 14:58:09.97ID:p7TzmKlx
>>322
ズバリのページありがとうございます!
324デフォルトの名無しさん
垢版 |
2020/11/24(火) 21:59:32.67ID:wabd38wc
どういたしまして
2020/11/25(水) 14:15:02.94ID:3ZJ1Ge7R
&mut TがCopyとCloneをimplしていないのは理解しているんだけど

let a: &mut i32 = &mut 0;
let b = a;
dbg!(a);

これがaがムーブされてエラーになって

let a: &mut i32 = &mut 0;
let b: &mut i32 = a;
dbg!(a);

これがエラーにならないのはナンデ?
2020/11/25(水) 14:51:10.49ID:wYoO0jiQ
>>325
それが借用でしょ。
2020/11/25(水) 14:59:59.26ID:wYoO0jiQ
>>325
b が使われないことはわかってるので無かったことになる。
b が使われるなら借用中ということでエラーになるよ。

↓ これはエラーになる。

let a: &mut i32 = &mut 0;
let b: &mut i32 = a;
dbg!(a);
dbg!(b);
2020/11/25(水) 15:24:43.58ID:s/U6WABr
これは僕もエラーにしてほしいなあ
何か深い理由があるんだろうけど…
2020/11/25(水) 22:28:12.61ID:70iTIiqa
let a: &mut i32 = &mut 0;
let b: &mut i32 = a;
dbg!(b);
dbg!(a);

これをOKにしたいんだから3行目が無くてもOKなのは必然
2020/11/25(水) 22:32:25.21ID:g8/riQpL
エラーにしたい理由がよく分からんな。
実際bを使ってないんならエラーになる意味がないし、
typoでbを使い損ねてるならbが未使用のwarningは出るから気付けるし。
2020/11/26(木) 02:46:48.20ID:Hqg/GFYt
>>329
えっ? て思ったけど確かに通った……
どっちも同じ&mut i32に見えてライフタイムが違うのか
2020/11/26(木) 10:22:00.12ID:LVnm3iYq
fn noop<T>(t: T) -> T {
t
}

let a: &mut i32 = &mut 0;
let b = noop(a);
dbg!(b);
dbg!(a);

これはエラーになる

let a: &mut i32 = &mut 0;
let b: &mut i32 = noop(a);
dbg!(b);
dbg!(a);

エラーにならない
ナンデ?
2020/11/26(木) 14:53:19.68ID:LVnm3iYq
https://users.rust-lang.org/t/questions-about-mut-t-and-move-semantics-mut-t-is-move-only/37484/13
ナンデかわかりました
implicit reborrowというものらしいです
2020/11/26(木) 16:45:55.16ID:02Rh/1GY
俺も↓これみてやっと分かった
https://github.com/rust-lang/rust/issues/35919#issuecomment-304130115
https://stackoverflow.com/a/58587870

関数のシグニチャの場合を含めて型が明示されてれば
&mut T -> & mut Tの場合でもimplicit reborrowが発生してmoveじゃなくなる
(auto-reborrowやreborrow coercionと呼んでる人も)

今まで気にしたことなかったわ
2020/11/26(木) 17:14:06.85ID:O9/RzT4k
なんでこんなの入れたんだろう…
2020/11/26(木) 18:11:09.60ID:02Rh/1GY
Type Coercionの一貫
ここに少し理由が書いてある
https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/check/coercion/index.html

↓これも同じ理由でエラーにならない
let a: &mut i32 = &mut 0;
let b = a as &mut i32;
dbg!(b);
dbg!(a);
2020/11/26(木) 23:01:58.61ID:SYxS73xz
最後にアクセスしたところで借用が終了すると思えば特に違和感はない
2020/11/26(木) 23:48:56.99ID:O9/RzT4k
変数宣言時に決まらず、今後スコープが終わるまでに使われるか使われないかで変わってしまうのか
2020/12/04(金) 00:56:22.75ID:g/NRvcV0
>>334
>&mut T -> & mut Tの場合でもimplicit reborrowが発生してmoveじゃなくなる
stackoverflowの方でも説明されてるけど、&mut T -> & mut Tじゃなくて&'a mut T -> &'b mut Tだな。
2020/12/04(金) 03:01:18.62ID:2+VKdPy1
implicitにする必要あった?
便利さより明示・明確で行って欲しい
2020/12/04(金) 11:37:04.89ID:OAjYDL2x
>>334のstackoverflowのコメント見れば必要だとしか
間違えたら単にコンパイルエラーになるわけで
342デフォルトの名無しさん
垢版 |
2020/12/06(日) 23:56:40.78ID:0jqklMIU
imple Trait for Something のTraitとSomething、逆の方が良かったなぁ
トレイトはまとめてモジュールにされることあるからimportしてからstructの直下でimplするからimpl struct with traitのほうが可読性高い、git的にも綺麗な差分の表示にもなるし
これなんか明確な理由とかないのかな?
2020/12/07(月) 00:00:26.20ID:owPfoMMb
ないでしょうね
どっちにでも設計できたでしょうし
2020/12/07(月) 00:39:06.96ID:O/wMvD4W
昔は impl Struct :Trait {} だった気がする
: だとどっちがどっちかわかりにくいみたいな議論はあったような
2020/12/07(月) 00:39:59.19ID:O/wMvD4W
あと impl Struct with Trait だと Struct "を" 実装すると読めるのがイマイチな気はする
2020/12/07(月) 01:03:15.94ID:BaEMz00S
impl Struct with Traitだと複数書くと同一Structを何回もimplすることになってちょっと変かも
このあたりはネイティブだと「てにをは」がおかしい感じに見えるのかもね
2020/12/08(火) 21:05:17.59ID:4EYeOh4b
lifetime関係で文句言われまくって暗黙にした部分が多いんだろう。。そんな輩にrust使わせる必要なんてないのに。
2020/12/09(水) 00:30:14.37ID:jODQKuwy
暗黙はイヤだあぁ〜っ!!
2020/12/09(水) 10:40:53.58ID:LSaC/unp
適当なライフタイムパラメータをつけるとコンパイルできることもあると学んだ
2020/12/09(水) 13:24:40.25ID:WuZTb4kZ
qiitaに久々に良記事あったわ
2020/12/09(水) 13:27:46.69ID:jODQKuwy
>>350
ヒントくれ
2020/12/10(木) 11:18:18.25ID:U7s1vwLT
>>296
可読性と言うか記述性が悪いし、そもそも厳密な仕様が公開されていない
部分が多い。例えば後者についてはライフタイムとか。
2020/12/10(木) 11:43:02.02ID:U7s1vwLT
>>294
実際には沢山あって、例えば、makefileやUnixのシェルスクリプト、BATファイル、
Perlの関数呼び出しなんかがある。
2020/12/10(木) 11:57:47.75ID:U7s1vwLT
正規表現やLISPなんかも可読性が低い。
2020/12/10(木) 12:16:53.52ID:hyB2wVsL
LISPが可読性低いはモグリ
2020/12/10(木) 12:25:40.73ID:YXjbRyJb
クポー!
2020/12/10(木) 12:41:56.12ID:oYgS32h8
>>352
具体的な記述例上げてくれないと何の説得力も無いぞ
2020/12/10(木) 15:03:07.81ID:YBB2SlAl
いつものヤバイ人だってすぐわかるだろ
荒らしの相手をするのも荒らしだぞ
2020/12/11(金) 11:56:33.87ID:/1hdqM5e
Cを日常的に使っていた人がRustに移行しようとするとやりたいことが出来なくて
馬鹿馬鹿しくなる。
数学的には完全に安全な書き方なのにRustには怒られる。
2020/12/11(金) 12:12:02.16ID:NpU6prgS
Rust by Example によれば
drop が (自動で) 呼ばれるのは「スコープの終わり」と書いてあるけど、
それは変わってないと考えていいよね?
最終のアクセスがスコープのまんなからへんだったとしても、
drop はスコープの最後ってのは今でも保証されるんだよね?
2020/12/11(金) 12:22:51.07ID:aOnuSvpC
っぱ、D言語よ
2020/12/11(金) 12:39:48.46ID:RI9UvvOD
>>360
>>289
2020/12/11(金) 18:10:27.06ID:7ILiijQb
数学的に完全に安全であるって証明を必要十分な早さで必要十分な量のコードに対して出きる人なら
おとなしくC使ってた方が良いんじゃないですかね
2020/12/11(金) 20:55:17.88ID:FrajMXPf
>>359
自信あるならコード見せてみな?
https://play.rust-lang.org/
2020/12/12(土) 01:56:14.01ID:4q8SABHv
>>364
いやです。
2020/12/12(土) 01:56:52.38ID:4q8SABHv
>>363
少なくともRustは使いません。
2020/12/12(土) 02:31:40.86ID:ub7HMY53
>>366
さようなら
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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