公式
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を学ぶ際に犯しがちな12の過ち
https://dystroy.org/blog/how-not-to-learn-rust
※Rustのasyncについて知りたければ「async-book」は必読
https://rust-lang.github.io/async-book/
※C++との比較は専用スレへ
C++ vs Rust
https://mevius.5ch.net/test/read.cgi/tech/1619219089/
※次スレは原則>>980が立てること
前スレ
Rust part14
https://mevius.5ch.net/test/read.cgi/tech/1644596656/
Rust part15
■ このスレッドは過去ログ倉庫に格納されています
2022/05/12(木) 18:28:20.99ID:cuIcFT6k
2022/05/14(土) 00:13:13.84ID:BgvoYA7m
>>13
foo! の定義中の foo! 呼び出しを $crate::foo!() みたいにすればいけるんじゃないかな
foo! の定義中の foo! 呼び出しを $crate::foo!() みたいにすればいけるんじゃないかな
2022/05/14(土) 03:12:50.47ID:J3IrN4Ey
>>14
それだ、ありがとう
それだ、ありがとう
16デフォルトの名無しさん
2022/05/14(土) 23:50:01.31ID:7gZW+FH0 前スレで出ていたこの上限チェックRangeFromだけど
fn countup<T>(start: T) -> impl Iterator<Item=T>
where T: Clone + TryFrom<usize> + num::CheckedAdd,
{
let one = T::try_from(1).ok().unwrap();
itertools::unfold((start, true), move |(n, is_first)| {
if *is_first {
*is_first = false;
Some(n.clone())
} else {
n.checked_add(&one)
.map(|new| { *n = new.clone(); new })
}
})
}
フラグ持たずにOptionで持ったほうがわかりやすくない?
fn countup<T>(start: T) -> impl Iterator<Item=T>
where T: Clone + TryFrom<usize> + num::CheckedAdd,
{
let one = T::try_from(1).ok().unwrap();
itertools::unfold(Some(start), move |n| {
let ret = n.clone();
if let &mut Some(ref m) = n {
*n = m.checked_add(&one);
}
ret
})
}
fn countup<T>(start: T) -> impl Iterator<Item=T>
where T: Clone + TryFrom<usize> + num::CheckedAdd,
{
let one = T::try_from(1).ok().unwrap();
itertools::unfold((start, true), move |(n, is_first)| {
if *is_first {
*is_first = false;
Some(n.clone())
} else {
n.checked_add(&one)
.map(|new| { *n = new.clone(); new })
}
})
}
フラグ持たずにOptionで持ったほうがわかりやすくない?
fn countup<T>(start: T) -> impl Iterator<Item=T>
where T: Clone + TryFrom<usize> + num::CheckedAdd,
{
let one = T::try_from(1).ok().unwrap();
itertools::unfold(Some(start), move |n| {
let ret = n.clone();
if let &mut Some(ref m) = n {
*n = m.checked_add(&one);
}
ret
})
}
2022/05/15(日) 00:14:36.59ID:AindqZB4
複オジに毒されてるな
successors(Some(start), move |n| n.checked_add(&one))
successors(Some(start), move |n| n.checked_add(&one))
2022/05/15(日) 02:25:52.10ID:/oKjcqbB
>>16
そのclone()は不要
トレイト境界からCloneを外せる
fn countup<T>(start: T) -> impl Iterator<Item=T>
where T: TryFrom<usize> + num::CheckedAdd,
{
let one = T::try_from(1).ok().unwrap();
itertools::unfold(Some(start), move |n| {
if let &mut Some(ref m) = n {
let mut next = m.checked_add(&one);
std::mem::swap(n, &mut next);
next
} else {
None
}
})
}
そのclone()は不要
トレイト境界からCloneを外せる
fn countup<T>(start: T) -> impl Iterator<Item=T>
where T: TryFrom<usize> + num::CheckedAdd,
{
let one = T::try_from(1).ok().unwrap();
itertools::unfold(Some(start), move |n| {
if let &mut Some(ref m) = n {
let mut next = m.checked_add(&one);
std::mem::swap(n, &mut next);
next
} else {
None
}
})
}
2022/05/15(日) 03:11:19.26ID:gyw6bZ1I
unfoldでなんでもできるからunfoldしか使わなくなってしまった人
いろいろな人
いろいろな人
2022/05/15(日) 07:53:49.50ID:SgXGf86o
>>18
take()?でもっと簡潔に書ける
fn countup<T>(start: T) -> impl Iterator<Item=T>
where T: TryFrom<usize> + num::CheckedAdd,
{
let one = T::try_from(1).ok().unwrap();
itertools::unfold(Some(start), move |n| {
let cur = n.take()?;
*n = cur.checked_add(&one);
Some(cur)
})
}
take()?でもっと簡潔に書ける
fn countup<T>(start: T) -> impl Iterator<Item=T>
where T: TryFrom<usize> + num::CheckedAdd,
{
let one = T::try_from(1).ok().unwrap();
itertools::unfold(Some(start), move |n| {
let cur = n.take()?;
*n = cur.checked_add(&one);
Some(cur)
})
}
2022/05/15(日) 08:07:10.15ID:SgXGf86o
>>19
unfoldは要点に絞って見やすい短縮記法として使われている
そのままunfoldを使わずに普通に構造体にimpl Iteratorする形へ置き換え可能なところがメリット
例えば>>20はそのまま機械的に以下へ展開できて同じく動作する
struct Countup<T> {
one: T,
n: Option<T>,
}
fn countup<T>(start: T) -> impl Iterator<Item=T>
where T: TryFrom<usize> + num::CheckedAdd,
{
Countup {
one: T::try_from(1).ok().unwrap(),
n: Some(start),
}
}
impl<T> Iterator for Countup<T>
where T: num::CheckedAdd,
{
type Item = T;
fn next(&mut self) -> Option<T> {
let cur = self.n.take()?;
self.n = cur.checked_add(&self.one);
Some(cur)
}
}
これだと長く冗長なので敢えてunfold利用版を記述することで要点のみに絞ることができる
unfoldは要点に絞って見やすい短縮記法として使われている
そのままunfoldを使わずに普通に構造体にimpl Iteratorする形へ置き換え可能なところがメリット
例えば>>20はそのまま機械的に以下へ展開できて同じく動作する
struct Countup<T> {
one: T,
n: Option<T>,
}
fn countup<T>(start: T) -> impl Iterator<Item=T>
where T: TryFrom<usize> + num::CheckedAdd,
{
Countup {
one: T::try_from(1).ok().unwrap(),
n: Some(start),
}
}
impl<T> Iterator for Countup<T>
where T: num::CheckedAdd,
{
type Item = T;
fn next(&mut self) -> Option<T> {
let cur = self.n.take()?;
self.n = cur.checked_add(&self.one);
Some(cur)
}
}
これだと長く冗長なので敢えてunfold利用版を記述することで要点のみに絞ることができる
2022/05/15(日) 10:14:06.42ID:2aUGzSw0
2022/05/15(日) 10:54:06.34ID:+6kSxcdv
unfoldより関係が分かりにくくなるけど
キャプチャした変数を使うfrom_fnという手もある
fn countup<T>(start: T) -> impl Iterator<Item=T>
where T: TryFrom<usize> + num::CheckedAdd,
{
let mut n = Some(start);
let one = T::try_from(1).ok().unwrap();
std::iter::from_fn(move || {
let cur = n.take()?;
n = cur.checked_add(&one);
Some(cur)
})
}
キャプチャした変数を使うfrom_fnという手もある
fn countup<T>(start: T) -> impl Iterator<Item=T>
where T: TryFrom<usize> + num::CheckedAdd,
{
let mut n = Some(start);
let one = T::try_from(1).ok().unwrap();
std::iter::from_fn(move || {
let cur = n.take()?;
n = cur.checked_add(&one);
Some(cur)
})
}
2022/05/15(日) 10:54:14.40ID:duXfvT8B
大人が集まってくつろいでるところに
子供がガラッと入ってきて九九の暗唱しはじめたら
頑張ってるのがほほえましくて応援しちゃうでしょ
でも
大人がガラッと入ってきて九九の暗唱しはじめたら
ギョッとするし不安になってくるやろ
なぜそんなもんをお披露目しちゃうのか
なぜ得意げになって頑張ってるのかわからない
もういいよ!と単に言えばいいのか
続きはカーチャンに見えもらってね!と言えば良いのか
言って分かってもらえる気配もないので怖い
子供がガラッと入ってきて九九の暗唱しはじめたら
頑張ってるのがほほえましくて応援しちゃうでしょ
でも
大人がガラッと入ってきて九九の暗唱しはじめたら
ギョッとするし不安になってくるやろ
なぜそんなもんをお披露目しちゃうのか
なぜ得意げになって頑張ってるのかわからない
もういいよ!と単に言えばいいのか
続きはカーチャンに見えもらってね!と言えば良いのか
言って分かってもらえる気配もないので怖い
2022/05/15(日) 11:10:33.42ID:+6kSxcdv
今回はこれでもいい
fn countup<T>(start: T) -> impl Iterator<Item=T>
where T: TryFrom<usize> + num::CheckedAdd,
{
let one = T::try_from(1).ok().unwrap();
std::iter::successors(Some(start), move |n| n.checked_add(&one))
}
fn countup<T>(start: T) -> impl Iterator<Item=T>
where T: TryFrom<usize> + num::CheckedAdd,
{
let one = T::try_from(1).ok().unwrap();
std::iter::successors(Some(start), move |n| n.checked_add(&one))
}
2022/05/15(日) 11:16:38.61ID:yna4qlqc
はちみつおじさん悔しそうwww
2022/05/15(日) 12:24:43.22ID:Q7/PweS0
九九と違って子供用のおもちゃプログラムでしか使えないコードなんだよなぁ
2022/05/15(日) 12:39:00.79ID:+mKsOYSe
代案出さずに文句だけつける万年野党みたいなやつがいるな
2022/05/15(日) 13:13:50.62ID:gyw6bZ1I
2022/05/15(日) 14:22:42.46ID:Cy+Jf1ha
九九のように簡単だという皆さま方に質問です
countup()が7通り(?)も色んな書き方が出てきて驚いたのですが
フィボナッチ数列だとどんな華麗なコードになりますか?
fn fibonacci<T>() -> impl Iterator<Item=T>
where T: TryFrom<usize> + num::CheckedAdd,
{
// ここを記述
}
出力仕様は一番ベーシックな0スタートとします
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
countup()が7通り(?)も色んな書き方が出てきて驚いたのですが
フィボナッチ数列だとどんな華麗なコードになりますか?
fn fibonacci<T>() -> impl Iterator<Item=T>
where T: TryFrom<usize> + num::CheckedAdd,
{
// ここを記述
}
出力仕様は一番ベーシックな0スタートとします
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
2022/05/15(日) 15:13:51.95ID:4TECkVdc
>>30
「Rustのお題スレ」でも立ててそっちでやってくれ
「Rustのお題スレ」でも立ててそっちでやってくれ
2022/05/15(日) 15:27:49.70ID:Cy+Jf1ha
2022/05/15(日) 15:40:51.12ID:hZXiQ87C
2022/05/15(日) 15:49:35.48ID:AAncJnA8
2022/05/15(日) 16:09:35.61ID:Cy+Jf1ha
>>33
ぜひそれを披露してやり方を教えてください
ぜひそれを披露してやり方を教えてください
2022/05/15(日) 16:27:05.61ID:KYkY1Akn
フィボナッチ数列イテレータ前スレでだれかが書いてたでしょ
それじゃいかんの
それじゃいかんの
2022/05/16(月) 07:04:42.44ID:nGMMRLLq
>>36
CopyやCloneを使っているから別問題だろう。
一般的にRustのプログラミングでは、
Copy(暗黙的な自動コピー)やClone(clone()による明示的な手動コピー)を使うと楽になるが、コストは高くなる。
そのため不要なclone()を見極めてそれを回避するプログラミングが出来るかどうか、というRustにおける根源的な話だろう。
CopyやCloneを使っているから別問題だろう。
一般的にRustのプログラミングでは、
Copy(暗黙的な自動コピー)やClone(clone()による明示的な手動コピー)を使うと楽になるが、コストは高くなる。
そのため不要なclone()を見極めてそれを回避するプログラミングが出来るかどうか、というRustにおける根源的な話だろう。
2022/05/16(月) 07:28:24.60ID:JrfUQrzl
Copyのコストが高い?
2022/05/16(月) 08:00:50.97ID:nGMMRLLq
2022/05/16(月) 08:58:48.98ID:tFcB4vDN
複製おじさんはいつも自分勝手な妄想を「一般的には~」とか「皆は~」と言って自分を正当化しようとするよね
2022/05/16(月) 10:03:10.22ID:0DWo1Xps
2022/05/16(月) 11:11:33.48ID:02kk6/+P
おじさん使いの人の自演がいつもよくわからん
唐突に妄想(?)を攻撃し出すが幻覚か何か見えてるのか
唐突に妄想(?)を攻撃し出すが幻覚か何か見えてるのか
2022/05/16(月) 16:19:03.24ID:NE3SiQoq
>>39
Cloneのコストが高い型にCopyを実装するな
Cloneのコストが高い型にCopyを実装するな
2022/05/16(月) 16:30:48.20ID:JLeK8lGd
Copyはコストが一番高いから出来る限り避けるべきだな
特にヒープを使うならCloneまでにしておくべき
可能ならばCloneも避けるべきだが
特にヒープを使うならCloneまでにしておくべき
可能ならばCloneも避けるべきだが
2022/05/16(月) 18:08:42.72ID:ThGcWJJo
Copyは所有権を複製するから最も高コスト(キリッ!!
2022/05/16(月) 18:10:04.46ID:ThGcWJJo
もはやどのレスもギャグにしか見えん
俺のしってるCopyとは確実に違う
俺のしってるCopyとは確実に違う
2022/05/16(月) 18:38:28.59ID:qW5+0T97
今までで一番意味不明なこと言ってるな
Copyのコストが高いならmoveのコストはどうなるのよ
Copyのコストが高いならmoveのコストはどうなるのよ
2022/05/16(月) 18:44:18.84ID:Mb2xQVjt
2022/05/16(月) 18:47:50.19ID:/5k6Bg80
Rust のムーブはビットパターンのコピーだもんな。
低レイヤの視点で見たらコピーと何の差も無い。
なるべく参照を使う場合にしても間接参照の実行コストとコピーの実行コストを天秤にかけてどちらが有利かは場合による。
低レイヤの視点で見たらコピーと何の差も無い。
なるべく参照を使う場合にしても間接参照の実行コストとコピーの実行コストを天秤にかけてどちらが有利かは場合による。
2022/05/16(月) 18:55:12.38ID:W7mPHnnh
>>47
それは理解不足すぎるぜ
大文字のCopyはCopyトレイトを意味しCopyトレイトを実装するか否かの話だろ
moveは別方向の話であり比較対象にすらならない
比較するならば「Copy実装(必然的にClone)も実装」「Cloneのみ実装」「どちらも実装なし」の3つだな
それは理解不足すぎるぜ
大文字のCopyはCopyトレイトを意味しCopyトレイトを実装するか否かの話だろ
moveは別方向の話であり比較対象にすらならない
比較するならば「Copy実装(必然的にClone)も実装」「Cloneのみ実装」「どちらも実装なし」の3つだな
2022/05/16(月) 19:00:08.16ID:GLqKLCqS
2022/05/16(月) 19:06:18.85ID:78bNbDCr
>>49
デタラメすぎ
ムーブでビットパターンのコピーは発生しない
ビットパターンのコピーが発生するのは引数の値渡し等であってムーブとは関係ない
さらに引数の値渡しでのでビットパターンのコピーとCopyのコピーも全く異なる
Copyのコピーはディープであって高コスト
デタラメすぎ
ムーブでビットパターンのコピーは発生しない
ビットパターンのコピーが発生するのは引数の値渡し等であってムーブとは関係ない
さらに引数の値渡しでのでビットパターンのコピーとCopyのコピーも全く異なる
Copyのコピーはディープであって高コスト
2022/05/16(月) 19:08:38.74ID:NE3SiQoq
そもそもフィボナッチ数列イテレータなんて誰も求めてないので
前スレのだれかさんの実装に問題があると思うなら自分で勝手に改善してなさい
そしてその結果はここに貼らなくていいぞ
前スレのだれかさんの実装に問題があると思うなら自分で勝手に改善してなさい
そしてその結果はここに貼らなくていいぞ
2022/05/16(月) 19:11:06.58ID:zgsMMZOB
「ヒープ使うならCloneまでにしとけ」
このセリフが一番刺さった
このセリフが一番刺さった
2022/05/16(月) 19:11:50.62ID:rHnqcaqs
>>52
おじさんマジかよwww
おじさんマジかよwww
2022/05/16(月) 19:22:59.76ID:NE3SiQoq
>>54
Dropを実装する型はCopyを実装できないよ
BoxもRcもStringもVecもそもそもCopyを実装できないので、するかしないか考えること自体が無意味
どういう型にCopyを実装できるか、できないか、すべきかはdocsに書いてあるので
なんのかんの言う前にまずはこれを読もうね
https://doc.rust-lang.org/std/marker/trait.Copy.html
Dropを実装する型はCopyを実装できないよ
BoxもRcもStringもVecもそもそもCopyを実装できないので、するかしないか考えること自体が無意味
どういう型にCopyを実装できるか、できないか、すべきかはdocsに書いてあるので
なんのかんの言う前にまずはこれを読もうね
https://doc.rust-lang.org/std/marker/trait.Copy.html
2022/05/16(月) 19:37:56.79ID:tTdd7GU5
2022/05/16(月) 19:45:37.77ID:/5k6Bg80
>>52
じゃあムーブでなにが起こるとおもってんの?
じゃあムーブでなにが起こるとおもってんの?
2022/05/16(月) 19:54:25.89ID:SHnkjBGX
2022/05/16(月) 20:38:11.38ID:NE3SiQoq
フィボナッチがどうでもいいならこの話は終わりです
2022/05/16(月) 20:45:13.08ID:Mz4z3EAu
関数の深いところから順に構造体をムーブで返していって
各関数で渡ってきた構造体のアドレスを表示させてみた
#[derive(Debug)]
struct S([i32; 100]);
fn main() {
let mut s1 = sub1(100);
s1.0[1] = 111;
println!("s1: {:p}", &s1);
println!("{s1:?}");
}
fn sub1(p: i32) -> S {
let q = p + 3;
let mut s2 = sub2(q);
s2.0[2] = p - 300;
println!("s2: {:p}", &s2);
s2
}
fn sub2(s: i32) -> S {
let t = s * 2;
let mut s3 = S([123; 100]);
s3.0[3] = t;
println!("s3: {:p}", &s3);
s3
}
s1もs2もs3もアドレスが一致
ムーブではアドレスそのままであり
ビットパターンのコピーが為されないという結論
各関数で渡ってきた構造体のアドレスを表示させてみた
#[derive(Debug)]
struct S([i32; 100]);
fn main() {
let mut s1 = sub1(100);
s1.0[1] = 111;
println!("s1: {:p}", &s1);
println!("{s1:?}");
}
fn sub1(p: i32) -> S {
let q = p + 3;
let mut s2 = sub2(q);
s2.0[2] = p - 300;
println!("s2: {:p}", &s2);
s2
}
fn sub2(s: i32) -> S {
let t = s * 2;
let mut s3 = S([123; 100]);
s3.0[3] = t;
println!("s3: {:p}", &s3);
s3
}
s1もs2もs3もアドレスが一致
ムーブではアドレスそのままであり
ビットパターンのコピーが為されないという結論
2022/05/16(月) 20:58:36.88ID:qW5+0T97
>>50
"Copyのコストが高い" は Copy を実装する行為そのもののコストが高いと解釈すべきということ?
そんなばかな
>>52
ドキュメント読みましょうねー
https://doc.rust-lang.org/stable/std/marker/trait.Copy.html
> It’s important to note that in these two examples, the only difference is whether you are allowed to access x after the assignment.
> Under the hood, both a copy and a move can result in bits being copied in memory, although this is sometimes optimized away.
...
> The behavior of Copy is not overloadable; it is always a simple bit-wise copy.
...
> The implementation of Clone can provide any type-specific behavior necessary to duplicate values safely.
> For example, the implementation of Clone for String needs to copy the pointed-to string buffer in the heap.
"Copyのコストが高い" は Copy を実装する行為そのもののコストが高いと解釈すべきということ?
そんなばかな
>>52
ドキュメント読みましょうねー
https://doc.rust-lang.org/stable/std/marker/trait.Copy.html
> It’s important to note that in these two examples, the only difference is whether you are allowed to access x after the assignment.
> Under the hood, both a copy and a move can result in bits being copied in memory, although this is sometimes optimized away.
...
> The behavior of Copy is not overloadable; it is always a simple bit-wise copy.
...
> The implementation of Clone can provide any type-specific behavior necessary to duplicate values safely.
> For example, the implementation of Clone for String needs to copy the pointed-to string buffer in the heap.
2022/05/16(月) 21:06:43.52ID:qW5+0T97
>>61
アドレスが同じか否かでコピーの有無を判断する意味はよくわからんが
その理屈だとこのコードだと違うアドレスが表示されるからビットパターンのコピーがされてるって結論になるのか?
#[derive(Debug)]
struct S([i32; 100]);
fn main() {
let mut s1 = S([0; 100]);
println!("s1: {:p}", &s1);
let s2 = s1;
println!("s2: {:p}", &s2);
}
アドレスが同じか否かでコピーの有無を判断する意味はよくわからんが
その理屈だとこのコードだと違うアドレスが表示されるからビットパターンのコピーがされてるって結論になるのか?
#[derive(Debug)]
struct S([i32; 100]);
fn main() {
let mut s1 = S([0; 100]);
println!("s1: {:p}", &s1);
let s2 = s1;
println!("s2: {:p}", &s2);
}
2022/05/16(月) 21:07:20.55ID:f/Xu02FO
>>61
struct S {}
fn main() {
let s1 = S{};
println!("s1: {:p}", &s1);
let s2 = s1;
println!("s2: {:p}", &s2);
}
struct S {}
fn main() {
let s1 = S{};
println!("s1: {:p}", &s1);
let s2 = s1;
println!("s2: {:p}", &s2);
}
2022/05/16(月) 21:08:00.98ID:f/Xu02FO
ごめん被った。やっぱそう思うよね。
2022/05/16(月) 21:16:19.81ID:9Ab93Lwf
2022/05/16(月) 21:19:28.47ID:51EzJkQ/
2022/05/16(月) 21:30:56.46ID:W905eBh/
>>57
一番分かってないお前が言うなよw
一番分かってないお前が言うなよw
2022/05/16(月) 21:38:19.38ID:/vD2A9J9
>>61
高コストなCopyも実装してから確認してみてねww
高コストなCopyも実装してから確認してみてねww
2022/05/16(月) 21:38:29.32ID:NE3SiQoq
2022/05/16(月) 21:39:12.01ID:DoCeaK1g
>>67
デバッグビルドだけじゃなくリリースビルドでも確認してねw
デバッグビルドだけじゃなくリリースビルドでも確認してねw
2022/05/16(月) 21:42:44.19ID:51EzJkQ/
>>71
リリースモードでもどちらも同じ結果
リリースモードでもどちらも同じ結果
2022/05/16(月) 21:49:25.30ID:sElCPUyn
2022/05/16(月) 23:46:37.66ID:jfEIc0ZW
このスレはいつもおかしい人間たちが集まってるな
Rustの何が人を狂わせるんだ?
Rustの何が人を狂わせるんだ?
2022/05/17(火) 00:09:43.95ID:HbNyXd2X
おじさんイジリ飽きたので結論いっておく
Copyもmoveもスタックの中身をコピーしてるのは同じ
最適化によって不要なコピーが除去されるかどうかはLLVM次第
でかい配列やでかい構造体などの極一部を除けばCopyは参照の受け渡しよりも低コスト
ついでに言うと&TもCopy
Copyもmoveもスタックの中身をコピーしてるのは同じ
最適化によって不要なコピーが除去されるかどうかはLLVM次第
でかい配列やでかい構造体などの極一部を除けばCopyは参照の受け渡しよりも低コスト
ついでに言うと&TもCopy
2022/05/17(火) 00:26:01.61ID:+9bLcV37
2022/05/17(火) 02:09:56.03ID:2XRLgT14
>>76
ここでいうCopyのコストって具体的にどういう操作のコストのこと言ってる?
構造体データのbitwise-copyのこと?それとも別の何か?
Cloneやmoveの場合にそのコストは発生しないと主張しているの?
ここでいうCopyのコストって具体的にどういう操作のコストのこと言ってる?
構造体データのbitwise-copyのこと?それとも別の何か?
Cloneやmoveの場合にそのコストは発生しないと主張しているの?
2022/05/17(火) 02:13:55.30ID:tAEVG8cC
2022/05/17(火) 07:41:41.18ID:1GDSnWAB
>>78
俺も同じくCopyは自動的にclone()されると思ってた
そう思ってた理由はClone実装せずにCopy実装するとエラーとなるため
そこで実験
#[derive(Debug,Copy)]
struct S { not_cloned: usize, cloned: usize }
impl Clone for S {
fn clone(&self) -> Self {
S { not_cloned: self.not_cloned / 3, cloned: self.cloned }
}
}
fn main() {
let s0 = S { not_cloned: 123, cloned: 456 };
let s1 = s0.clone();
let s2 = s0; // copy
println!("Cloned: {s1:?}");
println!("Copied: {s2:?}");
}
結果
Cloned: S { not_cloned: 41, cloned: 456 }
Copied: S { not_cloned: 123, cloned: 456 }
別物になった…
俺も同じくCopyは自動的にclone()されると思ってた
そう思ってた理由はClone実装せずにCopy実装するとエラーとなるため
そこで実験
#[derive(Debug,Copy)]
struct S { not_cloned: usize, cloned: usize }
impl Clone for S {
fn clone(&self) -> Self {
S { not_cloned: self.not_cloned / 3, cloned: self.cloned }
}
}
fn main() {
let s0 = S { not_cloned: 123, cloned: 456 };
let s1 = s0.clone();
let s2 = s0; // copy
println!("Cloned: {s1:?}");
println!("Copied: {s2:?}");
}
結果
Cloned: S { not_cloned: 41, cloned: 456 }
Copied: S { not_cloned: 123, cloned: 456 }
別物になった…
2022/05/17(火) 10:53:02.16ID:GxF458pr
2022/05/17(火) 14:50:42.61ID:94ESmIzZ
ガイジムーブ来てんね
2022/05/17(火) 21:03:27.69ID:VS5jQHYL
Copyはshallow copyだわな
2022/05/17(火) 22:07:44.57ID:LjbtS7tD
色々と正確な情報が出揃ったところで質問
まず前提として話を明白かつ簡単にするため、
ここでは!DropつまりCopy実装可能な型のみ対象、
そしてもしClone実装するならば*selfつまりCopy実装と同一、
CloneやCopyを実装するかどうかは任意、
小文字のcloneとcopyはそれぞれCloneやCopyを実装した時にそれらが使われることを意味するとする
このとき、次のどちらの主張が正しい?
A「copy/cloneはコストが生じるので、回避できるならば回避したほうが有利」
B「copy/cloneのコストはmoveと同じなので回避する必要はない」
まず前提として話を明白かつ簡単にするため、
ここでは!DropつまりCopy実装可能な型のみ対象、
そしてもしClone実装するならば*selfつまりCopy実装と同一、
CloneやCopyを実装するかどうかは任意、
小文字のcloneとcopyはそれぞれCloneやCopyを実装した時にそれらが使われることを意味するとする
このとき、次のどちらの主張が正しい?
A「copy/cloneはコストが生じるので、回避できるならば回避したほうが有利」
B「copy/cloneのコストはmoveと同じなので回避する必要はない」
2022/05/17(火) 22:30:37.28ID:VUKzLr9a
場合による。
たとえコピーであっても結局は内容が同じものであると看破すれば
実際にはコピーしないようなコードを生成するといったことは有りうる。
Rust は原理的にエイリアス解析がやりやすい言語だと思うし。
実行コスト的にどうかなんて考えずに所有権管理の側面からの妥当性で決めたほうがよい。
その上でどうしても実行コストを切り詰めないといけないようになったならその時に考えればいい。
たとえコピーであっても結局は内容が同じものであると看破すれば
実際にはコピーしないようなコードを生成するといったことは有りうる。
Rust は原理的にエイリアス解析がやりやすい言語だと思うし。
実行コスト的にどうかなんて考えずに所有権管理の側面からの妥当性で決めたほうがよい。
その上でどうしても実行コストを切り詰めないといけないようになったならその時に考えればいい。
2022/05/17(火) 22:33:27.98ID:5/60CrrJ
2022/05/17(火) 23:40:20.70ID:XaJZCLYj
2022/05/17(火) 23:43:19.03ID:nlEgMvZ6
考えてみたけどmove/copyが問題になるレベルの大きさの型をスタックに置いて扱ったことが無いな…
使うとすれば固定長配列のバッファ?
でもそんなものmove/copyするわけないし
やっぱり考える意味の無い二択だと思う
使うとすれば固定長配列のバッファ?
でもそんなものmove/copyするわけないし
やっぱり考える意味の無い二択だと思う
2022/05/17(火) 23:47:41.13ID:FqAlYuq2
2022/05/17(火) 23:49:36.53ID:YviCLBk+
2022/05/17(火) 23:54:01.76ID:VUKzLr9a
2022/05/17(火) 23:55:13.39ID:tAEVG8cC
あっこの流れC++相談室で見たやつだ
2022/05/18(水) 00:07:06.58ID:P5Km+xQv
要は参照使えるなら使っとけって?
今更すぎませんか
今更すぎませんか
2022/05/18(水) 00:30:37.66ID:DGffctwq
オナコードペタペタされてたほうがマシだったなこりゃ
2022/05/18(水) 00:45:17.78ID:opn2S8Zb
>>92
それもあるが、例えば多数のコピーが行われているコードに対して、回避できる分を見直し、少数のコピーで済むように改善できる場合もある
Copy実装せずに明示clone()した方が見つけやすいかもしれない
それもあるが、例えば多数のコピーが行われているコードに対して、回避できる分を見直し、少数のコピーで済むように改善できる場合もある
Copy実装せずに明示clone()した方が見つけやすいかもしれない
2022/05/18(水) 01:26:17.77ID:lxQ5l4ey
2022/05/18(水) 01:42:43.25ID:d5NnfCmB
一人だけ間違った思い込みをしてるのに
説明されても「俺は間違ってない、間違ってるのはお前ら」が続くだけだからな
説明されても「俺は間違ってない、間違ってるのはお前ら」が続くだけだからな
2022/05/18(水) 01:46:16.75ID:6ezlEFaX
2022/05/18(水) 01:51:55.82ID:Da/MVUm8
2022/05/18(水) 02:06:14.30ID:UgigdTUo
100デフォルトの名無しさん
2022/05/18(水) 07:08:20.63ID:bcZKOTNR 大きいフィールドを持つ型には、Copyは実装しないだろうし普通はCopy/Moveのコスト差を気にすることなくない?
どちらにすべきかボーダーが難しいことはありそうだけど
どちらにすべきかボーダーが難しいことはありそうだけど
101デフォルトの名無しさん
2022/05/18(水) 07:14:11.27ID:P5Km+xQv >>94
データフローを見直して単純に消せるclone/copyは消せってことか?
それこそ今更すぎるわ
単純に消せないところまで消した後、さらにパフォーマンス改善するにはどうするかってことで、参照の話か?って聞いたんだけど
どこの誰とも知れないやつのフィボナッチのコードに対する指摘をされても知らねーよ
問題があって対策が分かってるなら自分で直すがいい
データフローを見直して単純に消せるclone/copyは消せってことか?
それこそ今更すぎるわ
単純に消せないところまで消した後、さらにパフォーマンス改善するにはどうするかってことで、参照の話か?って聞いたんだけど
どこの誰とも知れないやつのフィボナッチのコードに対する指摘をされても知らねーよ
問題があって対策が分かってるなら自分で直すがいい
102デフォルトの名無しさん
2022/05/18(水) 07:41:25.51ID:4GWzufxp103デフォルトの名無しさん
2022/05/18(水) 07:56:39.00ID:HgdHe2aE104デフォルトの名無しさん
2022/05/18(水) 08:12:27.72ID:BE/QrV8J 流れからすると本当はジェネリックのフィボナッチにCopyを付けないほうが有利と主張したかったんじゃね?
でも後から回避できないことに気づいて苦しい言い訳を重ねてるだけと見た
でも後から回避できないことに気づいて苦しい言い訳を重ねてるだけと見た
105デフォルトの名無しさん
2022/05/18(水) 08:21:27.45ID:6swlbHlO >>85
根拠も示さず批判だけする一番アカン人間やな
根拠も示さず批判だけする一番アカン人間やな
106デフォルトの名無しさん
2022/05/18(水) 08:33:04.08ID:6hDwlDoy >>104
フィボナッチはCopyを回避できないものなの?
フィボナッチはCopyを回避できないものなの?
107デフォルトの名無しさん
2022/05/18(水) 08:45:43.18ID:2HNq06l+ 分からないなら分からないから教えてって言えばいいのに意地を張るからこうなる
構えば構うほど意味不明な発言が出てくる
真面目に議論したいならせめてIDコロコロ変えるのやめな
構えば構うほど意味不明な発言が出てくる
真面目に議論したいならせめてIDコロコロ変えるのやめな
108デフォルトの名無しさん
2022/05/18(水) 09:10:15.39ID:Gy2qdhBc フィボナッチってこれだろ
f(0) = 0
f(1) = 1
f(n) = f(n - 1) + f(n - 2)
関数呼び出しに足し算に大量のコピーは避けられない
f(0) = 0
f(1) = 1
f(n) = f(n - 1) + f(n - 2)
関数呼び出しに足し算に大量のコピーは避けられない
109デフォルトの名無しさん
2022/05/18(水) 09:28:25.87ID:3vPi03ro >>87
async関数やasyncブロックで生成されるFutureは結構大きくなることがあって、boxingした方が性能出るケースもある
async関数やasyncブロックで生成されるFutureは結構大きくなることがあって、boxingした方が性能出るケースもある
110デフォルトの名無しさん
2022/05/18(水) 10:05:07.09ID:jV65BxdQ111デフォルトの名無しさん
2022/05/18(水) 10:20:40.09ID:AWXqkW+Q >>110
型制約からCopyを外せばプリミティブと言えどもcopyされなくなる
具体的には個々のプリミティブ型へモノモーフィゼーゼーションされる前の段階でCopy実装していない型に対してのcopy発生エラーが生じる
フィボナッチでcopyを回避するのは可能
型制約からCopyを外せばプリミティブと言えどもcopyされなくなる
具体的には個々のプリミティブ型へモノモーフィゼーゼーションされる前の段階でCopy実装していない型に対してのcopy発生エラーが生じる
フィボナッチでcopyを回避するのは可能
112デフォルトの名無しさん
2022/05/18(水) 10:38:43.35ID:2JRtSvHV 複オジの主張まとめ(1)
37, 39, 44
=====
CopyやCloneを使っているから別問題だろう。
一般的にRustのプログラミングでは、
Copy(暗黙的な自動コピー)やClone(clone()による明示的な手動コピー)を使うと楽になるが、コストは高くなる。
そのため不要なclone()を見極めてそれを回避するプログラミングが出来るかどうか、というRustにおける根源的な話だろう。
もちろんCopyは最もコストが高い。
個々のコスト自体は通常clone()と同じだが、常に自動的にclone()が起きるため最もコストが高くなる。
Copyはコストが一番高いから出来る限り避けるべきだな
特にヒープを使うならCloneまでにしておくべき
可能ならばCloneも避けるべきだが
37, 39, 44
=====
CopyやCloneを使っているから別問題だろう。
一般的にRustのプログラミングでは、
Copy(暗黙的な自動コピー)やClone(clone()による明示的な手動コピー)を使うと楽になるが、コストは高くなる。
そのため不要なclone()を見極めてそれを回避するプログラミングが出来るかどうか、というRustにおける根源的な話だろう。
もちろんCopyは最もコストが高い。
個々のコスト自体は通常clone()と同じだが、常に自動的にclone()が起きるため最もコストが高くなる。
Copyはコストが一番高いから出来る限り避けるべきだな
特にヒープを使うならCloneまでにしておくべき
可能ならばCloneも避けるべきだが
113デフォルトの名無しさん
2022/05/18(水) 10:39:05.95ID:2JRtSvHV 複オジの主張まとめ(2)
50, 52, 57
=====
それは理解不足すぎるぜ
大文字のCopyはCopyトレイトを意味しCopyトレイトを実装するか否かの話だろ
moveは別方向の話であり比較対象にすらならない
比較するならば「Copy実装(必然的にClone)も実装」「Cloneのみ実装」「どちらも実装なし」の3つだな
デタラメすぎ
ムーブでビットパターンのコピーは発生しない
ビットパターンのコピーが発生するのは引数の値渡し等であってムーブとは関係ない
さらに引数の値渡しでのでビットパターンのコピーとCopyのコピーも全く異なる
Copyのコピーはディープであって高コスト
これだけCopyやCloneを理解していない連中が多い状況だと
>>30の質問に答えられるかどうかは最低限クリアすべきテストとして有用ではないか?
フィボナッチ自体はもちろんどうでもよい話だがCopyやCloneを避けるRustの基本ができるかどうかわかる点で
50, 52, 57
=====
それは理解不足すぎるぜ
大文字のCopyはCopyトレイトを意味しCopyトレイトを実装するか否かの話だろ
moveは別方向の話であり比較対象にすらならない
比較するならば「Copy実装(必然的にClone)も実装」「Cloneのみ実装」「どちらも実装なし」の3つだな
デタラメすぎ
ムーブでビットパターンのコピーは発生しない
ビットパターンのコピーが発生するのは引数の値渡し等であってムーブとは関係ない
さらに引数の値渡しでのでビットパターンのコピーとCopyのコピーも全く異なる
Copyのコピーはディープであって高コスト
これだけCopyやCloneを理解していない連中が多い状況だと
>>30の質問に答えられるかどうかは最低限クリアすべきテストとして有用ではないか?
フィボナッチ自体はもちろんどうでもよい話だがCopyやCloneを避けるRustの基本ができるかどうかわかる点で
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 日本行き空路49万件キャンセル 中国自粛呼びかけ 日本行きチケット予約の約32%に相当 ★4 [ぐれ★]
- 【音楽】Perfume・あ~ちゃんの結婚相手「一般男性」は吉田カバンの社長・吉田幸裕氏(41) 高身長で山本耕史似 [Ailuropoda melanoleuca★]
- 【大分】佐賀関で大規模火災、170棟以上が延焼中 70代男性1人と連絡取れず [ぐれ★]
- 【サッカー】U-17日本代表、激闘PK戦制す 北朝鮮撃破で6大会ぶり8強入り U17W杯 [久太郎★]
- 【インバウンド】中国人観光客の日本での消費額は年間約2兆円超…中国政府は公務員の出張取り消し [1ゲットロボ★]
- 【サッカー】日本代表、ボリビアに3発快勝 森保監督通算100試合目を飾る…鎌田、町野、中村がゴール [久太郎★]
- 自閉症が「んなっしょい」と連呼するお🏡
- アンケート調査で「高市発言は問題なし」 93.5%wwwwwwwwwwwwwwwwwwwwwwwww [279254606]
- じゃあ何故俺がここまで独身チーズ男性を嫌っているか理由が分かる?
- クマの救急医「ヘルメット被れ」 [787212328]
- 生活保護の受給額ってなんでこんなに安いの?
- 自民党議員「高市は先人が築き上げた日中関係を壊した。外務省が謝罪に言ってるが自分で責任を取れ」 [834922174]
