◎正当な理由による書き込みの削除について:      生島英之とみられる方へ:

Rust part13 YouTube動画>2本 ->画像>1枚


動画、画像抽出 || この掲示板へ 類似スレ 掲示板一覧 人気スレ 動画人気順

このスレへの固定リンク: http://5chb.net/r/tech/1636247099/
ヒント:5chスレのurlに http://xxxx.5chb.net/xxxx のようにbを入れるだけでここでスレ保存、閲覧できます。

1デフォルトの名無しさん2021/11/07(日) 10:04:59.35ID:pJhT3MIE
公式
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
http://2chb.net/r/tech/1619219089/

※次スレは原則>>980が立てること

前スレ
Rust part12
http://2chb.net/r/tech/1629813327/

2デフォルトの名無しさん2021/11/07(日) 10:05:36.56ID:pJhT3MIE
Rust The Book (日本語版)
https://doc.rust-jp.rs/book-ja/
Rust edition guide (日本語版)
https://doc.rust-jp.rs/edition-guide/
Rust by example (日本語版)
https://doc.rust-jp.rs/rust-by-example-ja/
Rust cookbook (日本語版)
https://uma0317.github.io/rust-cookbook-ja/
Rust API guideline (日本語版)
https://sinkuu.github.io/api-guidelines/
Rust nomicon book (日本語版)
https://doc.rust-jp.rs/rust-nomicon-ja/
Rust WASM book (日本語版)
https://moshg.github.io/rustwasm-book-ja/
Rust embeded book (日本語版)
https://tomoyuki-nakabayashi.github.io/book/
Rust enbeded discovery (日本語版)
https://tomoyuki-nakabayashi.github.io/discovery/

3デフォルトの名無しさん2021/11/07(日) 10:06:41.30ID:pJhT3MIE
Rust CLI (Command Line Interface) apps Book
https://rust-cli.github.io/book/
Rust async-std Book
https://book.async.rs/
Rust The Unstable Book
https://doc.rust-lang.org/nightly/unstable-book/
Rust rustc Book
https://doc.rust-lang.org/rustc/
Rust Cargo Book
https://doc.rust-lang.org/cargo/
The Rust Reference
https://doc.rust-lang.org/reference/
The Rust Standard Library
https://doc.rust-lang.org/std/

4デフォルトの名無しさん2021/11/07(日) 12:23:40.47ID:yCoK9XU3

シャドーイングが困るのって関数がよっぽど長いときだけなんで問題にならんよね

5デフォルトの名無しさん2021/11/07(日) 13:02:12.62ID:BjoZRpKT
>前スレの質問「間違って同じ変数名つけたコード片突っ込んでしまった系だと他言語にあるらしい2重宣言エラーないの怖くないですか?」

他の言語でもスコープが違えば二重宣言エラーになりません
つまり他の言語でも意図しない同名変数ミスは同じように起き得ます
例えば以下はC言語の例

int c = 100;
int main() {
 int c = 200;
 {
  int c = 300;
 }
 printf("%d\n", c); /* コンパイルは通って 200 となる */
}

Rustのシャドーイングは同じブロックスコープでも同名変数が通りますが
仮にミスで同名変数を付けたコードを挿入してしまったとしても
・その時点で先行の変数が既にライフタイム尽きていれば影響ゼロ
・その時点で先行の変数のライフタイムがあって割り込む形になる場合
  ・それ以降で二度の消費が発生して借用エラー発生となる可能性が高い
  ・先行の変数が一度も使われていない段階なら未使用warning発生
  ・型が違っていれば割り込む形であっても型違いでエラー発生
と影響ゼロもしくは引っかかる可能性が高いでしょう

>>4
おっしゃる通り、そもそも意図しない同名変数に気付かない時点で「その関数は長すぎ」ですね

6デフォルトの名無しさん2021/11/07(日) 13:03:26.24ID:GwJCd0Qm
ある値をちょっとだけ処理したものにどんな名前を付けたいかってのは、
まあ適した名前があるならそれに越したことは無いけど
同じ名前を付けることによってたいした違いはない、かつ以前の値にアクセスすることはもうないことが明示できるので
それはそれで使いようはあるよ。

以前の値にアクセスしないという意思を持ってシャドーイングを使うのでそれで困ることはない。
うっかりで同じ名前を付けてしまった場合も大抵の場合は型の違いとかで検出されるし。

7デフォルトの名無しさん2021/11/07(日) 14:26:48.84ID:c7aT0NV0
何を問題にしてるのか分からんけど、コンパイラから見たら、同じ変数名宣言でも連番で構文解析しているわけで
ブロックスコープによりシャドーされても何ら関係ないが、インライン展開して最適化するrustコードだと問題が
出る場合もありうる。それとシャドーと以前の値にアクセスすることはもうない事は意味が違う

8デフォルトの名無しさん2021/11/07(日) 14:35:43.57ID:GwJCd0Qm
>>7
間接的にアクセスしうるとかいうのはもちろんあるけど、
あくまでもプログラマが読み書きする上での意図として明示するという意味ね。
実際にもう (直接には) 使えないんだから使えないという意味だよ。

9デフォルトの名無しさん2021/11/07(日) 14:45:10.83ID:K5DEbKWG
ん?まあありうるだろうけど、そんな意図を持ってシャドーイングをするコードは捨てろよ?明示じゃねーわ

10デフォルトの名無しさん2021/11/07(日) 15:07:42.51ID:GwJCd0Qm
そうか。

11デフォルトの名無しさん2021/11/07(日) 15:10:45.19ID:XJB+ymj6
>>996
C/C++だとスコープ中で外のスコープの宣言と被ってたら警告出るよね

12デフォルトの名無しさん2021/11/07(日) 15:27:52.97ID:BjoZRpKT
>>7
>それとシャドーと以前の値にアクセスすることはもうない事は意味が違う

それはシャドーされてもスコープ終了と異なり、尽きてなければライフライムは残ってるという話だよね?
例えば
let mut a = vec![1,2,3];
let b = &mut a;
let a = [4,5,6];
b.extend(a);
assert_eq!(b, &[1, 2, 3, 4, 5, 6]);

>>11
被ってるCのコード>>5を今gcc test.cしたけどその警告出ない

13デフォルトの名無しさん2021/11/07(日) 16:09:12.89ID:XJB+ymj6
おま環

14デフォルトの名無しさん2021/11/07(日) 16:58:36.83ID:NoqiBvXu
intellijでも、シャドーイングがあったときは警告出てなかったっけ?

15デフォルトの名無しさん2021/11/07(日) 17:10:25.95ID:qLFsTeDp
変数名にシャドーイングって含めとけばいいのでは

16デフォルトの名無しさん2021/11/07(日) 17:23:30.13ID:BGBI+61D
そんなことよりもだ!Rustに限らないけど
これって誰も食いつかないんだけど、1と2どっちが良いか、そろそろ決着つけてくれ
let upper = 1000;
// 1、これと
let mut acc = 0;
for n in 0.. {
  let n_squared = n * n;
  if n_squared >= upper {
    break;
  } else if n_squared % 2 == 1 {
    acc += n_squared;
  }
}

// 2、これ
let acc1: u32 = (0..).map(|n| n * n)
 .take_while(|&n_squared| n_squared < upper)
 .filter(|&n_squared| is_odd(n_squared))
 .fold(0, |acc, n_squared| acc + n_squared);

17デフォルトの名無しさん2021/11/07(日) 17:27:45.44ID:Vt90/0HU
foldじゃなくてsumのほうが良いのでは

18デフォルトの名無しさん2021/11/07(日) 17:29:32.83ID:TOVMzjUd
let acc1: u32 = (0..).map(|n| n * n)
 .take_while(|&n_squared| n_squared < upper)
 .filter(is_odd)
 .sum()

199912021/11/07(日) 17:45:31.24ID:tLg/y1Lc
>>5
不意のミスでも結構コンパイルで引っかかってくれるようで安心しました。Rustさんよく考えられてますね。知りたかったことが書いてありました。ご丁寧にありがとうございます

20デフォルトの名無しさん2021/11/07(日) 18:44:40.25ID:jMCdC4Py
shadowing嫌いな人はdeny(clippy::shadow_same)などすればよい

21デフォルトの名無しさん2021/11/07(日) 18:52:44.84ID:UxYGnxuj
>>16
High orders functionはソースが配列かイテレーターか、いずれかで注意が必要です。配列の場合は以下の
英文のようになります。つまりそのサイズのメモリー領域が必要になるということです。またイテレータの
時でもある程度メモリーは当然使用しますが、それよりも遅延評価されるので注意が必要です。
Note on performance and stack usage
Unfortunately, usages of this method are currently not always optimized as well as they could be.
This mainly concerns large arrays, as mapping over small arrays seem to be optimized just fine.
Also note that in debug mode (i.e. without any optimizations), this method can use a lot of stack space
(a few times the size of the array or more).
Therefore, in performance-critical code, try to avoid using this method on large arrays or check
the emitted code. Also try to avoid chained maps (e.g. arr.map(...).map(...)).
個人的には深いチェーン呼び出しはあまり好きではありません。なぜなら状態をデバックしにくいからです。
パフォーマンス的な罠がありデバックしにくい事を抜けば、map,take_while,filterなどは何を行うかforに
比べ意図が明確になりますが、それは自己満足の幅が大きいとも言えます

22デフォルトの名無しさん2021/11/07(日) 19:20:41.26ID:AmV/cRIg
>>18のコードは大きな配列とかメモリ大量消費とかしないだろ
小さなstructを以下の4つ消費するのみで誤差
RangeFrom, Map, TakeWhile, Filter

23デフォルトの名無しさん2021/11/07(日) 19:35:16.03ID:UxYGnxuj
>>22
18のコードは配列ではなくイテレーターなのでそうですが、map,take_while,filterのほうが
好みの人が多いとは思いますが、私が言いたいのは何でもかんでもHigh orders functionに
して書くのはよく知らないと、リスクがあるということとブレークポイントなどを仕掛けて
経過は見れないということです。日本語が読めない人はもう少し考えましょう

24デフォルトの名無しさん2021/11/07(日) 19:40:56.86ID:BxmvbDqp
メソッドチェーンなら、メソッドごとに単体テストができるし、テストを用意しとけばすぐにバグがわかるような気がするが。

25デフォルトの名無しさん2021/11/07(日) 21:07:08.18ID:UxYGnxuj
ほんと日本語読めない奴ばっかり。経過いうてるのにメソッド毎だとか、バグのことなんて言って
ないのに(特殊な例を言えば配列の場合でmap().map()などとしたメモリー使用量)を言っている
のに、そもそも個人的には言うてんのに、そんなに説得したいのか?

26デフォルトの名無しさん2021/11/07(日) 21:12:13.09ID:0IMrdMn2
翻訳は、Chrome, Edge の翻訳機能、

Google の翻訳サイトとか、DeepL とか

27デフォルトの名無しさん2021/11/07(日) 21:12:13.85ID:t/1xwUA+
経過も見れるよ

28デフォルトの名無しさん2021/11/07(日) 21:20:10.03ID:UxYGnxuj
言語は素晴らしいのにやってる奴が意識高い系のウンコ野郎ばっかり

29デフォルトの名無しさん2021/11/07(日) 21:27:42.49ID:aMDc0Kvs
まあコミュニティに馴染めるかどうかも本人の適性によるところがあるしな

30デフォルトの名無しさん2021/11/07(日) 22:21:32.27ID:BjoZRpKT
>>25
前回から新たに導入されたfn map([T; N], FnMut(T) -> U) -> [U; N]を何度も使えば配列地獄になるけど
昔からあるIterator::map()を使えば小さな struct Mapの分しか容量を喰わないよ
前者: assert_eq!(10, [1, 2, 3, 4, 5].map(|n| n - 3).map(|n| n * n).into_iter().sum());
後者: assert_eq!(10, [1, 2, 3, 4, 5].into_iter().map(|n| n - 3).map(|n| n * n).sum());
したがってこの件でメソッドチェーンを批判するのはおかしい
そして元々の>>16課題forを使うか>>18のメソッドチェーンを使うかの話に配列は一切関係ない

31デフォルトの名無しさん2021/11/07(日) 22:27:15.28ID:jMCdC4Py
配列とスライスとベクタが別物なのこういう場所で会話するときに地味に混乱しがち

32デフォルトの名無しさん2021/11/07(日) 22:28:05.16ID:jMCdC4Py
Stringとstrって日本語でどう呼び分けるんですか?

33デフォルトの名無しさん2021/11/08(月) 07:17:46.35ID:59xs5iEI
inspectで経過見れるじゃん

34デフォルトの名無しさん2021/11/08(月) 07:29:23.24ID:n6XCACTA
>>30
こういう内容ゼロの事を言ってる意識高い系が普及を邪魔してる。自身が”何度も使えば配列地獄になるけど”と
認めてるにも関わらず、最初からイテレータを使えばと先に言ってることをそのまま返す
何が”したがって”なのか全然分からんが、説明した気になり、”チェーンを使うかの話に配列は関係ない”と
まとめる。そもそもチェーンを批判なんてしてない(対象によりけり高階関数の連続使用はメモリーを圧迫する
可能性があるということだけ)それとも言い負かしたいだけの気持ち悪さをそんなに使用者に伝えたいのか?

35デフォルトの名無しさん2021/11/08(月) 07:59:01.69ID:SITQ70se
>>25
君が二つの全く異なるmap()をゴチャ混ぜにして皆を騙して混乱させているだけだ
我々はfor文で回すかイテレータをチェーンするかの話をしている
君が持ち出した[T; N]::map()は配列を配列に変換するのみでイテレータと一切関係ない
我々はmap()に関しては一貫してIterator::map()の話しかしていない

36デフォルトの名無しさん2021/11/08(月) 08:32:39.74ID:fuBvo+92
ほんとここに来るやつは皆を騙す詐欺師の気持ちや悪い奴ばかり、一切関係ないぞ!

37デフォルトの名無しさん2021/11/08(月) 10:16:54.73ID:csyRALBm
どんなに適当に書いてもコンパイラさんがうまいこと最適化してくれるのでヨシ!

38デフォルトの名無しさん2021/11/08(月) 10:32:52.09ID:xhkp7neH
最初から大して違いも出ないが、分かりやすさを重視するなら高階関数かな?
これはこう書け!と口煩くいってくる奴が理解できないけど…
でも裾野を広げるためには未熟で冗長なコードでも許容しなきゃね、1つもfor無しで
デカいプロジェクトを書くことなんて無いし、趣味でやってるだけなら縛りもありだが

39デフォルトの名無しさん2021/11/08(月) 10:39:48.75ID:XWIn4U6b
高階関数でかくと並列化しやすいからそう書いてる

40デフォルトの名無しさん2021/11/08(月) 11:16:30.19ID:NiBBbin2
>>39
rayonなどに移行しやすいという意味?

41デフォルトの名無しさん2021/11/08(月) 11:23:59.38ID:OCI2yhfb
rustの得意とする高パフォーマンス領域だとactix(-web)なんかはスレッド数=物理コア数で
下手に並列化しないほうがrequest/secは高いから、標準の高階関数も並列にはなっていない
訳で、バッチ処理みたいなその時に他の処理が走ってなくて、如何に処理時間を短くするか
というプログラムなら最初からRayonとか最初に導入してそう…
状態共有しない並列起動だけなら、thread::spawn(|| { for i in 0..x {...} }でも比較的に
簡単に出来るが、そういう意味では無いんだろう

42デフォルトの名無しさん2021/11/08(月) 11:28:09.63ID:hB1EvZ1K
さすが長文w
中身がナッシング

43デフォルトの名無しさん2021/11/08(月) 12:29:17.17ID:QzkUvy+x
>皆を騙す詐欺師の気持ち悪い奴ばかり

都合悪くなると話題変えて逃げるしな

44デフォルトの名無しさん2021/11/08(月) 12:33:26.36ID:4QnDXIIG
async/awaitが高階関数と(今の所)相性良くない

45デフォルトの名無しさん2021/11/08(月) 12:45:54.28ID:ODzJsaPg
話題変えて逃げてんじゃねーよ!カス!

46デフォルトの名無しさん2021/11/08(月) 13:17:11.03ID:NiBBbin2
>>44
今のところとしてるのは改善策が取り込まれる見込みだから?
それとも単に将来のことはわからない程度の意味?

47デフォルトの名無しさん2021/11/08(月) 13:48:44.02ID:vASCcAjA
静的チェックでオールOKみたいな言語って意識高い系のバカを呼び寄せやすいんだよ。
奴らは動的テストなんてしたくないって意識をすぐ誤魔化す癖がついてる。

48デフォルトの名無しさん2021/11/08(月) 14:48:38.73ID:xhY6YpeY
ストローマンがあらわれた

49デフォルトの名無しさん2021/11/08(月) 14:51:34.92ID:vASCcAjA
自分のことを言われて怒っちゃったのか。
わかりやすいね。

50デフォルトの名無しさん2021/11/08(月) 14:53:05.69ID:M7ed0MM2
>>32
ストリングとストラ
もしくは
ストリングとストリングスライス

51デフォルトの名無しさん2021/11/08(月) 15:29:22.26ID:GGqoyJW1
うん、完全理解した。こんスレは同じrustガンダム乗りなのに連邦の白い悪魔以外は認めないんだ
どっちでもいいじゃんか・・・
Rust part13 YouTube動画>2本 ->画像>1枚

52デフォルトの名無しさん2021/11/08(月) 17:38:09.25ID:7WV3o+af
Vecに入ったi32(空っぽの可能性もあり)の平均を計算するのってどうするのが一番スマート?

53デフォルトの名無しさん2021/11/08(月) 17:43:46.40ID:Chf4/Vgn
高階関数使う

54デフォルトの名無しさん2021/11/08(月) 20:19:03.35ID:QIO9hdEn
副作用持つときはfor文でそれ以外はメソッドチェーン繋げてやります

55デフォルトの名無しさん2021/11/08(月) 21:14:06.85ID:6BzlB5w0
>>34
イテレータの高階関数の連続使用でメモリーを圧迫することはないと思います
各イテレータ自体はコンパクトな構造体ですし高階関数自体の処理も基本的にはメモリーを圧迫するものではありません
ただし全ての要素を受け取らないと算出できない物もあるため一時的に長いVecを使うことになるイテレータもあります
この場合はイテレータを用いずに自分でforなどを回す方法をとっても同様にして一時的に長いVecを使うことになるでしょう

56デフォルトの名無しさん2021/11/08(月) 21:14:39.00ID:IC/lLBzS
そういや平均求めるメソッドってstd::iterにもitertoolsにもないんか?

57デフォルトの名無しさん2021/11/08(月) 21:38:29.05ID:NiBBbin2
>>47
Rustには動的テストを容易にする仕組みが入ってるしRustの話ではなさそうだ

58デフォルトの名無しさん2021/11/08(月) 21:38:34.43ID:3AO0oG+L
そんな簡単な実装を一々stdに入れてたら、糞関数だらけのLLライクになるじゃん?

59デフォルトの名無しさん2021/11/09(火) 04:01:57.70ID:d6arxLIn
>>58
std::iterに入れろとまでは思わないけど、
sumもcountもイテレータ消費しちゃうから微妙にめんどくさくない?

60デフォルトの名無しさん2021/11/09(火) 20:24:06.75ID:E/uEHC7F
>>59
こんな感じでsumとcountを同時に計算かな
trait Average<T> {
 fn average(self) -> T;
}
impl<I: Iterator<Item=T>, T: Zero + One + Add<Output=T> + Div<Output=T>> Average<T> for I {
 fn average(self: I) -> T {
  let (cnt, sum): (T, T) = self.fold((Zero::zero(), Zero::zero()), |(cnt, sum), n| (cnt + One::one(), sum + n));
  sum / cnt
 }
}
fn main() {
 assert_eq!(500, (1..1000).into_iter().average());
 assert_eq!(6.8, vec![2.3, 8.7, 9.4].into_iter().average());
 assert_eq!(33, [1, 3, 5, 7, 9].into_iter().map(|n| n*n).average());
}

61デフォルトの名無しさん2021/11/09(火) 22:53:03.40ID:yHbe3Xjs
オーバーフローしないように型を選択することとか、
汎用的に使えて問題を避けることを考えたら平均を計算するのってそんなに簡単な話ではないと思う。

62デフォルトの名無しさん2021/11/10(水) 08:15:17.85ID:BLadVH6y
stats::median
今でもfilter使えだとかうっせーのばっかり、標準ライブラリは小さくて良いYO
https://lib.rs/science/math
statrs-dev/statrsとか好きなの引っ張ってきて入れろよ?平均じゃなくてもさ

63デフォルトの名無しさん2021/11/12(金) 17:23:46.15ID:pYLNCtl5
Vecとかに入った複数のtokio::task::JoinHandleをjoinするのはどうやるんでしょうか?

64デフォルトの名無しさん2021/11/12(金) 20:00:37.76ID:PXROpwUc
thread::JoinHandleは並列で(マルチスレッドとなり)
join()で待つ

task::JoinHandleは非同期で(シングルスレッド時は並行、マルチスレッド時は並列となり)
awaitで待つ

65デフォルトの名無しさん2021/11/12(金) 21:00:47.58ID:CuMBVxkM
futures::future::join_allでいいんじゃね

66デフォルトの名無しさん2021/11/12(金) 23:59:03.69ID:BY1dkyYH
task::JoinHandleの方はFuture trait実装なので
列挙ならfutures::join!(f1,f2,f3,...)マクロ
VecならIntoIteratorに対応のjoin_all(v) >>65

67デフォルトの名無しさん2021/11/17(水) 00:04:41.47ID:6Xk/Jjaa
おいウンコ引き取りに来いよ

68デフォルトの名無しさん2021/11/20(土) 19:33:51.68ID:i03LC++E
let mut a = 'a';
let mut d = 'd';

match 'b' {
 a..=d => { println!("true") }
 _ => { println!("false") }
}

matchでcharの範囲指定ができるからって試したんだけど、
変数に入れたcharだと範囲指定ってできないの?
これだとあんまり意味ないような

69デフォルトの名無しさん2021/11/20(土) 20:32:13.75ID:iQUqB4pW
パターンには代入される側の変数しか書けないけどガードは自由自在
fn test(b: char) -> bool {
 let a = 'a';
 let d = 'd';
 match b {
  _ if a <= b && b <= d => true,
  _ => false,
 }
}
fn main() {
 assert_eq!(test('b'), true);
 assert_eq!(test('x'), false);
}

70デフォルトの名無しさん2021/11/20(土) 20:43:54.76ID:iQUqB4pW
そして範囲指定を使いたいんだったらこう
  _ if (a..=d).contains(&b) => true,

71デフォルトの名無しさん2021/11/20(土) 20:49:00.01ID:iQUqB4pW
bのところが式かも知れないのでxにマッチさせてこの方がベターか
  x if (a..=d).contains(&x) => true,

72デフォルトの名無しさん2021/11/20(土) 21:28:17.44ID:i03LC++E
>>69
ありがとう 

if (a..=b).contains(&c) { println!("true") } else { println!("false"); };
って感じで試して見たけど、ガードで
(a..=b).contains(&c)にすればよさげだとわかった

73デフォルトの名無しさん2021/11/21(日) 01:21:54.59ID:VYuGYhJz
Rangeを含むジェネリックな関数を作りたいのですが例えば単純化した例
fn ntimes_print<T: num::Integer>(n: T, s: &str) {
 (0..n).for_each(|_| print!("{}", s));
}
ここでRangeのnがexpected integerと言われエラーになってしまい
上記のように型Tにnum::Integerトレイトを制約してみましたが上手くいきません
どうすれば型TとジェネリックのままRangeを使えるでしょうか?

74デフォルトの名無しさん2021/11/21(日) 01:26:47.07ID:mkw0m2hl
>>73
複数のトレイトは + で繋げることができるんやで

75デフォルトの名無しさん2021/11/21(日) 01:30:30.33ID:VYuGYhJz
>>74
はい
それで何のトレイトを繋げればいいですか?という質問です

76デフォルトの名無しさん2021/11/21(日) 02:02:32.44ID:VYuGYhJz
格闘しているうちにコンパイラがstableじゃダメだとかfeature指定しろとか無茶を言って来るので従ってnightlyにしたりfeature指定したりしたところようやく動いたのですが何か変ですよね

77デフォルトの名無しさん2021/11/21(日) 02:16:44.28ID:qtUeCPjG
うーん
引数に繰り返す回数渡せばいいような気がするんだけどそう簡単じゃないのね

78デフォルトの名無しさん2021/11/21(日) 02:30:42.73ID:VYuGYhJz
nightlyにせずstableのままで範囲指定nをジェネリック化できた方いましたらやり方教えて下さい

79デフォルトの名無しさん2021/11/21(日) 02:59:34.97ID:mkw0m2hl
>>75
ドキュメントをみるかぎり PartialOrd が要求されているでよ

80デフォルトの名無しさん2021/11/21(日) 03:09:03.92ID:qtUeCPjG
やりたいことってこんな感じ?
https://play.rust-lang.org/?version=stable&;mode=debug&edition=2021&gist=f97e7a0bd7775b88065da30bcf6a6a01

81デフォルトの名無しさん2021/11/21(日) 04:34:14.82ID:VYuGYhJz
>>79
入れたけどダメでした

>>80
違う
この形です
fn ntimes_print<T>(n: T, s: &str) {
 (0..n).for_each(|_| print!("{}", s));
}

82デフォルトの名無しさん2021/11/21(日) 10:25:42.94ID:szj4saah
リテラル`0`の問題とstd::iter::Stepがunstableなのと2つ問題を解決する必要がある

fn ntimes_print<T>(n: T, s: &str)
where T: num::Integer + num::ToPrimitive + Clone
{
num::range(T::zero(), n).for_each(|_| print!("{}", s));
}

83デフォルトの名無しさん2021/11/21(日) 11:02:09.61ID:VYuGYhJz
やはり..を使う限りstableでは無理でnightlyでないと以下のような素朴な実装も無理ということでしょうか
少し例を実用的に変えてみましたがトレイト境界(制約)を最小限で以下のようなコードでnightlyだと動いています

#![feature(step_trait)]

fn main() {
 let n = 5; // 任意の整数型
 n.times(|n| println!("OK {}", n));
}

trait Times<T: Sized> {
 fn times<F>(self, f: F) where F: FnMut(T) -> ();
}

impl<T> Times<T> for T where T: num::Zero + std::iter::Step {
 fn times<F>(self: T, f: F) where F: FnMut(T) -> () {
  (num::Zero::zero()..self).for_each(f);
 }
}

84デフォルトの名無しさん2021/11/21(日) 12:10:20.71ID:qtUeCPjG
https://play.rust-lang.org/?version=stable&;mode=debug&edition=2021&gist=3702e2291f04ef5e40bd5310079972b1

85デフォルトの名無しさん2021/11/21(日) 15:03:50.15ID:szj4saah
>>83
where
T: num::Integer,
Range<T>: Iterator<Item=T>,
とかにすればできるよ

86デフォルトの名無しさん2021/11/21(日) 16:08:27.58ID:VYuGYhJz
>>85
凄い!stableで..で動きました!ありがとう!

impl<T> Times<T> for T where T: num::Zero, std::ops::Range<T>: Iterator<Item=T> {
 fn times<F>(self: T, f: F) where F: FnMut(T) -> () {
  (num::Zero::zero()..self).for_each(f);
 }
}

87デフォルトの名無しさん2021/11/21(日) 18:59:28.56ID:a8amZ/lG
更にtimes()自体をイテレータにしてしまえば汎用的になるだけでなく
それらトレイト境界などのコードの記述も魔法のように消えて短くなる

fn main() {
 let n = 5; // 任意の整数型
 n.times().for_each(|n| println!("OK {}", n));
}

trait Times<T: Sized> {
 fn times(self) -> std::ops::Range<T>;
}

impl<T: num::Zero> Times<T> for T {
 fn times(self: T) -> std::ops::Range<T> {
  num::Zero::zero()..self
 }
}

これだけで動作する

88デフォルトの名無しさん2021/11/21(日) 20:22:13.92ID:ekMm5ue5
timesなら精々u64::MAX回も繰り返すことなさそうだしTからu64に変換するのではだめなの?

89デフォルトの名無しさん2021/11/21(日) 20:32:22.18ID:VYuGYhJz
トレイト境界が短くなって素晴らしい原因ですがもしかして
>>83では要のops::Range<T>型がコードに明示されてないので条件のiter::Stepを要求されてしまい
>>85ではそのops::Range<T>型をトレイト境界に登場させたためiter::Stepが不要となり
>>87ではそのops::Range<T>型を返り値として明記したためトレイト境界にも不要となった??

90デフォルトの名無しさん2021/11/22(月) 10:01:45.21ID:YMaXH3oe
指定するトレイト境界が減った代わりにAPIが劣化してる

91デフォルトの名無しさん2021/11/22(月) 11:46:24.84ID:EEj8G+es
>>90
イテレータ版の方がfor_each以外とも組み合わせられるからAPIとして良いと思う

>>87
しかしトレイト境界でnum::Zeroしか求められないのはstd::ops::Range周りの設計がおかしいと思われる
普通に実装すれば初期値(num::Zero)に増分(num::One)を加えて(ops::Add)いって比較(ops::PartialOrd)が必要となる
実際にnum::rangeによるイテレータ版times()の実装は Clone + PartialOrd + num::Zero + num::One となる

fn main() {
 let n = 5; // 任意の整数型
 n.times().for_each(|n| println!("OK {}", n));
}

trait Times<T: Sized> {
 fn times(self) -> num::iter::Range<T>;
}

impl<T: Clone + PartialOrd + num::Zero + num::One> Times<T> for T {
 fn times(self: T) -> num::iter::Range<T> {
  num::range(T::zero(), self)
 }
}

92デフォルトの名無しさん2021/11/22(月) 12:13:59.22ID:qBbb57Hy
わざわざ外部crateと独自trait使って
n.times().for_each(f)にするくらいなら
(0..n).for_each(f)で十分

93デフォルトの名無しさん2021/11/22(月) 12:33:40.60ID:EEj8G+es
>>92
それでは最初の条件のジェネリックを満たせていない
>>88
状況によってはそのように強引にu64へ変換できても対応できなくなるケースもある
例えば単純な例として文字'x'からのみなる文字列による型Xを考えてみよう
#[derive(Debug,Clone,PartialEq,PartialOrd)]
struct X(String);
impl X {
 fn new(s: &str) -> Self {
  if !s.chars().all(|c| c == 'x') {
   panic!("not x");
  }
  X(s.to_string())
 }
}
これで文字'x'以外は使えない文字列の型が出来上がり
あとは>>91で必要なZeroとOneとAddを定義すれば動くはず
impl num::Zero for X {
 fn zero() -> X { X::new("") }
 fn is_zero(&self) -> bool { self.0 == "" }
}
impl num::One for X {
 fn one() -> X { X::new("x") }
}
impl std::ops::Add for X {
 type Output = X;
 fn add(self, rhs: X) -> X { X(self.0.clone() + &(rhs.0)) }
}

94デフォルトの名無しさん2021/11/22(月) 12:45:37.77ID:EEj8G+es
>>93の続き
ところがnumクレートのOneは不必要に掛け算のMulも要求してきた
仕方ないので呼び出したらパニックするimplを加える
impl std::ops::Mul for X {
 type Output = X;
 fn mul(self, _rhs: X) -> X {
  panic!("mul() for X")
 }
}
さらになぜかnum::ToPrimitiveも要求してきたのでこれもパニック実装する
impl num::ToPrimitive for X {
 fn to_i64(&self) -> Option<i64> {
  panic!("to_i64() for X")
 }
 fn to_u64(&self) -> Option<u64> {
  panic!("to_u64() for X")
 }
}
これで>>91のnum::range利用イテレータ版times()が動くはず
そういえばDisplay実装を忘れたのでDebug表示
fn main() {
 let n = X::new("xxxxx");
 n.times().for_each(|n| println!("OK {:?}", n));
}
実行結果:
OK X("")
OK X("x")
OK X("xx")
OK X("xxx")
OK X("xxxx")
ちゃんと数値型以外でも動きました

95デフォルトの名無しさん2021/11/22(月) 15:04:22.59ID:UzgCqcLK
>>93
>それでは最初の条件のジェネリックを満たせていない
ジェネリックにしたければ(T::zero()..n).for_each(f)と書けばいいだけでしょ
単にRangeを返すだけのメソッドを手間かけて微妙に抽象化しても周りが迷惑するだけだぞ

96デフォルトの名無しさん2021/11/22(月) 15:23:28.68ID:EEj8G+es
>>95
ところがT::zero()..nだと動かない
さきほどの>>93の型Xはnum::range利用だと動いたが
let n = X::new("xxxxx");
(X::zero()..n).for_each(|n| println!("OK {:?}", n));
としようとすると以下のコンパイルエラー
the following trait bounds were not satisfied:
`X: Step`
つまりnightlyでないと使えないstd::iter::Stepを満たしていないと言われる

97デフォルトの名無しさん2021/11/22(月) 19:21:50.63ID:fRCpO7Rh
どうしてもstableでやりたいという話ならRangeとStepを独自に用意するしかなさそう
n..mという表記は使えないが、n.times()なら支障なく実装できるかと

自分なら以下みたいに書くけどね
(T: From<i32> + PartialOrd が前提)

(0..).map(T::from).take_while(move ¦x¦ x<n)

98デフォルトの名無しさん2021/11/22(月) 19:36:28.33ID:3Rtka3dv
なるほどね

99デフォルトの名無しさん2021/11/22(月) 19:55:09.41ID:5egSOJea
>>97
それだとT: From<i32>という無関係で不要な強い条件を満たさないといけないため
例えば>>93の型Xでは動かないね
シンプルにZero、One、Add、PartialOrdだけで実装したほうが良さそう

100デフォルトの名無しさん2021/11/22(月) 20:04:43.45ID:VyYbXHRo
C++じゃないんだから不毛な型パズルはやめろ

101デフォルトの名無しさん2021/11/22(月) 20:25:52.53ID:gBMgBg1g
C++よりマシ

102デフォルトの名無しさん2021/11/22(月) 20:56:45.47ID:MJpN6tlo
意味のない例で延々とよくやるわ

103デフォルトの名無しさん2021/11/22(月) 21:02:15.85ID:FLi/1Joa
カスタムな型ならRangeよりイテレータ対応が先

104デフォルトの名無しさん2021/11/22(月) 21:09:17.05ID:fRCpO7Rh
StepがunstableなのはさておきFromLiteralみたいなトレイトがあるとZeroやOneの出番が減ってうれしいのかね
T: FromLiteralの時に整数リテラルがT型の値として解釈されるようになるようなイメージ

105デフォルトの名無しさん2021/11/22(月) 21:58:50.69ID:FLi/1Joa
try_into()でできるよ

106デフォルトの名無しさん2021/11/22(月) 22:09:34.28ID:fRCpO7Rh
言葉足らずでしたね

struct Foo;
が FromLiteral を実装しているときに
let n: T = 123;
というコードを書くとコンパイラが
let n = T::from_literal("123");
といったコードに変換してくれるイメージ

from_literalはconst fnにできてコンパイル時にエラー検出できるとベター

107デフォルトの名無しさん2021/11/22(月) 22:10:11.00ID:fRCpO7Rh
>>106
TはFooの間違い

108デフォルトの名無しさん2021/11/23(火) 07:57:08.78ID:9DtS3af5
ねこ

109デフォルトの名無しさん2021/11/23(火) 10:28:33.41ID:8Ju98kPx
https://github.com/rust-lang/team/pull/671
Coreチームがクソだからやめたった、ってこと?

110デフォルトの名無しさん2021/11/23(火) 13:56:03.32ID:b1gEfTjX
const fnが言いたいだけやろ、だれが=演算子でcopyでもなく、言語上ないことになってるコンストラクタでもなく
そんな特異なトレイトを勝手に呼ぶのが嬉しいねん、なにがバター犬や

111デフォルトの名無しさん2021/11/23(火) 14:58:36.02ID:s6k3uLQ1
>>110
= が特殊な振る舞いをするのではなくて
整数リテラルが組み込み整数型についてgenericな数値になるという振る舞いを
FromLiteralを実装した型に広げようという案のつもりです

112デフォルトの名無しさん2021/11/23(火) 20:05:14.41ID:1c3aeddQ
m..nをiter::Step使わず素直にPartialOrd + One + Addだけで実装してくれれば汎用的で分かりやすいと思う

struct Range<T> {
 start: T,
 end: T,
}
fn range<T>(start: T, end: T) -> Range<T> {
 Range { start, end }
}
impl<T: Clone + PartialOrd + One + Add<Output=T>> Iterator for Range<T> {
 type Item = T;
 fn next(&mut self) -> Option<T> {
  if self.start < self.end {
   let result = self.start.clone();
   self.start = self.start.clone() + T::one();
   Some(result)
  } else {
   None
  }
 }
}
fn main() {
 let n :Vec<u8> = range(1, 5).collect();
 let x :Vec<X> = range(X::new("x"), X::new("xxxxx")).collect();
 println!("{:?}", n); // [1, 2, 3, 4]
 println!("{:?}", x); // [X("x"), X("xx"), X("xxx"), X("xxxx")]
}
>>93のX型でも動いたよ

113デフォルトの名無しさん2021/11/23(火) 20:38:59.43ID:rocYZd+S
特徴もないリテラルを勝手に解釈するとかあり得んわ
現状だって0b0011u32とか0x80u32とか書いてるのに、型定義が横にあるからそれでコンパイル時に
パース処理したいなんてそんな都合の良い言語ちゃうだろ、Raw stringのr"123"とか、Raw bytesとか
とも違うし、確かにfrom_strが"123"を解釈するけどやるにしても、let x: i32 = "123";が通ってから。
でもコンパイル時とはいえ自動型変換に見えるコードは承認しないと思うし、直行性も下がる
こんな場末の酒場みたいな所で言ってもコミッターどころかforと高階関数で揉める駄スレにどうこう出来る内容ちゃう

114デフォルトの名無しさん2021/11/23(火) 20:58:16.83ID:Oek7vlRG
>>112
数値だからAdd+Oneが成り立つわけで
型Xとか何の意味もないぞ

115デフォルトの名無しさん2021/11/23(火) 22:14:31.32ID:qrGqDm2c
>>114
でも現実のプログラミングでは数値を生で使うよりも
struct Counter { usize } とか
struct Age { usize } とか
struct XxxLength { usize } とかにして
型が異なることをはっきりさせて安全に使いますよね
そして付加情報があればstructのフィールドが複数になることもあったり
あるいはstruct std::time::Durationのようにnanoからsecまで扱えるようにしてもAddをimplして使いますよね
つまり生の数値だけを対象にしていては視点が狭いと思うのです

116デフォルトの名無しさん2021/11/23(火) 22:15:57.50ID:qrGqDm2c
>>115の{ }は( )の誤記ですw

117デフォルトの名無しさん2021/11/24(水) 03:12:15.58ID:P1gN11rG
Stepがstable入りしたら要らなくなる話になにとんでもない破壊的変更を持ち出しているんだ

118デフォルトの名無しさん2021/11/24(水) 03:25:07.43ID:gceGN8+W
Age型をn.times().for_each()
Length型をn.times().for_each()
Duration型をn.times().for_each()

ジェネリックw

119デフォルトの名無しさん2021/11/24(水) 05:02:23.28ID:e1u6MioL
>>118
timesより>>112のm..n rangeイテレータが汎用的でいいんじゃね?

120デフォルトの名無しさん2021/11/24(水) 15:22:53.32ID:zkfKZqQ7
>>119
times()ですら無駄なのに>>112とかありえないよ
無価値どころか害悪レベルなんだけど

121デフォルトの名無しさん2021/11/24(水) 17:05:44.23ID:5wn/1hS5
>>117
コンパイラや標準ライブラリの変更で型推論の結果が変わることは破壊的変更扱いされなかったっけ

122デフォルトの名無しさん2021/11/24(水) 17:26:56.67ID:Zq3lnaBh
>>106
なんとなく分かりましたがいきなりコンパイラが自動変換の前に現状で
例えばまずは整数型を例に絞ってやるとして
trait IntegerCompatible {
 type Integer;
 fn into_integer(&self) -> Self::Integer;
 fn from_integer(n: Self::Integer) -> Self;
}
こんな感じのトレイトにして
まずは利便性のために整数型自体に自分を返すよう実装しておいて
macro_rules! integer_compatible {
 ($($t:ty)*) => ($(
  impl IntegerCompatible for $t {
    type Integer = $t;
    #[inline]
    fn into_integer(&self) -> Self::Integer {
     *self
    }
    #[inline]
    fn from_integer(n: Self::Integer) -> Self {
     n
    }
  }
 )*)
}
integer_compatible! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
あとは今はコンパイラ支援がないので
使う時に自分でinto_integerして計算などして結果をfrom_integerする感じですかね

123デフォルトの名無しさん2021/11/24(水) 17:39:27.77ID:Zq3lnaBh
>>122の続き
実際に使ってみる具体例として面倒なので>>112をそのまま使うと
struct Range<T> {
 start: T,
 end: T,
}
このあたりはそのまま使うとして
fn range<T>(start: T, end: T) -> Range<T> {
 Range { start, end }
}
実装部分ではジェネリックT型にOneやAddなどを求められていたのを
CloneとIntegerCompatible要求だけに変えて整数型IにOneやAddなどを移動
impl<T, I> Iterator for Range<T> where
 T: Clone + IntegerCompatible<Integer=I>,
 I: Copy + PartialOrd + num::One + std::ops::Add<Output=I>, {
 type Item = T;
 fn next(&mut self) -> Option<T> {
  if T::into_integer(&self.start) < T::into_integer(&self.end) {
    let result = self.start.clone();
    self.start = T::from_integer(T::into_integer(&self.start) + I::one());
    Some(result)
 } else {
    None
  }
 }
}
今はコンパイラ支援がないので手動変換ですが自動もしくは簡便な記法に出来そう
あと整数型にはいちいちOneやAddやPartialOrdを書かなくても済むように出来そう

124デフォルトの名無しさん2021/11/24(水) 17:47:29.36ID:Zq3lnaBh
>>123の続き
念のため実際に使う時にどうなるかと使えるかを確認すると
let n :Vec<u128> = range(3, 7).collect();
println!("{:?}", n); // [3, 4, 5, 6]
もちろん整数型自体は使えるのは当たり前なのでLength(usize)で使う場合
#[derive(Debug,Clone)]
struct Length(usize);
impl IntegerCompatible for Length {
 type Integer = usize;
 fn into_integer(&self) -> Self::Integer {
  self.0
 }
 fn from_integer(n: Self::Integer) -> Self {
  Length(n)
 }
}
このIntegerCompatible定義はこのような単純形ならマクロ化で出来そうですね
let v :Vec<Length> = range(Length(3), Length(7)).collect();
println!("{:?}", v); // [Length(3), Length(4), Length(5), Length(6)]
そして当然ながら動きました

125デフォルトの名無しさん2021/11/24(水) 17:56:43.20ID:Zq3lnaBh
>>124の続き
あとは>>93に出てきた変なX型ですね
#[derive(Debug,Clone)]
struct X(String);
impl X {
 fn new(s: &str) -> Self {
  if !s.chars().all(|c| c == 'x') {
    panic!("not x");
  }
  X(s.to_string())
 }
}
と定義はそのまま使っておきます
あとはOneやAddの実装はをせずにIntegerCompatibleだけ実装
impl IntegerCompatible for X {
 type Integer = usize;
 fn into_integer(&self) -> Self::Integer {
  self.0.len()
 }
 fn from_integer(n: Self::Integer) -> Self {
  X::new(&std::iter::repeat("x").take(n).collect::<String>())
 }
}
このような特殊例のみIntegerCompatible実装のマクロ化は無理ですね
let v :Vec<X> = range(X::new("xxx"), X::new("xxxxxxx")).collect();
println!("{:?}", v); // [X("xxx"), X("xxxx"), X("xxxxx"), X("xxxxxx")]
当然ですがX型についても動きました

126デフォルトの名無しさん2021/11/24(水) 18:18:05.49ID:AgL0hXz4
誰も見てねーから別のところでやれ

127デフォルトの名無しさん2021/11/24(水) 19:13:18.31ID:5wn/1hS5
話題がないんだもん
なんか話題を提供してくれ

128デフォルトの名無しさん2021/11/24(水) 23:19:00.01ID:e1u6MioL
結局Derefみたいにコンパイラが自動的に適用して変換してくれればそのintoやfromをプログラムには書かなくて済むんやろ

129デフォルトの名無しさん2021/11/25(木) 23:08:27.91ID:QVGqalzl
ファイルを開く操作って普通に考えたらFile::open_ほにゃらら()みたいなメソッドにOpenOptionsを渡すほうが自然だと思うんですが
OpenOptions::open()みたいな方法を取ってるのってどういう理由からなんでしょうか?

130デフォルトの名無しさん2021/11/25(木) 23:59:01.72ID:88pS2ZzI
>>129
・その方がメソッドチェーンで見やすい
・複雑な構造体を用意してそこに様々な値をセットして指定するインターフェースは非常に大変
・そのうえOS毎に違う部分もある

131デフォルトの名無しさん2021/11/26(金) 00:22:31.18ID:aH1+xhzE
>>129
Rustは関数定義でデフォルト値のあるオプション引数をサポートしてないから
オプション引数的な使い方をしたい場合はビルダーパターンを使うのが一般的

File::options().read(true).create(true).open("foo.txt”);みたいな使い方になる

132デフォルトの名無しさん2021/11/26(金) 09:37:38.31ID:kuMbCEJE
うーん
ダサいな
もっときれいにならんの?

133デフォルトの名無しさん2021/11/26(金) 09:50:01.95ID:kuMbCEJE
メソッドチェーンって過去の遺物だよね?
バグの温床だし
長いとどこかで消し忘れや二重指定が出て本人が気が付かなくなる
長くなっただけで破綻するんだからおかしい

134デフォルトの名無しさん2021/11/26(金) 10:00:30.74ID:5+U4u14D
>>133
一般的に今どきのプログラミング言語は全てメソッドチェーンが主流
もしかしてメソッドチェーンを使わない古い言語使いの方ですか?

135デフォルトの名無しさん2021/11/26(金) 10:06:22.27ID:yaO+xNFa
パイプライン演算子大好きとかLisp方面から来た人とかなのかも……

136デフォルトの名無しさん2021/11/26(金) 10:12:22.08ID:kuMbCEJE
え?メソッドチェーンってjqueryが流行ってたころの名残でしょ?
10年ぐらい前

メソッドチェーンなんて書いててだるいだけ

137デフォルトの名無しさん2021/11/26(金) 10:21:37.95ID:5+U4u14D
>>136
JavaScriptも今は関数型プログラミングが主流へと変わりメソッドチェーンだし外部ライブラリを使うインタフェースもメソッドチェーンがよく使われる
そしてRustも同様
どこの古い世界から来たお客さんですか?

138デフォルトの名無しさん2021/11/26(金) 10:34:43.95ID:E7I1X7f8
メソッドチェーンって関数型由来ではないし

139デフォルトの名無しさん2021/11/26(金) 11:18:59.37ID:/IsoxS9R
>>133
ビルダーは二重指定しても問題ない
消し忘れはどういう指定方法でも発生するからテストで防ぐ以外ないよ

テスト書かない文化の人?

140デフォルトの名無しさん2021/11/26(金) 11:23:55.78ID:/IsoxS9R
>>135
パイプ演算子も同じ問題抱えてるし
Lispでも今はthreadマクロで処理順に書く

141デフォルトの名無しさん2021/11/26(金) 11:31:53.80ID:oSCWFWAt
>>140
はえ〜、そうか勉強になったわ

142デフォルトの名無しさん2021/11/26(金) 11:44:41.28ID:kuMbCEJE
>>139
二重指定は一方でtrue一方でfalse指定しているパターン

143デフォルトの名無しさん2021/11/26(金) 12:05:35.16ID:SqSfLhr2
>>132
どうやったら綺麗なのか参考のため教えて
Rustじゃなくて他の言語でも
仮想の言語でもいいよ

144デフォルトの名無しさん2021/11/26(金) 12:25:05.02ID:kuMbCEJE
通常のCのオープン関数のほうが100倍キレイで簡潔で合理的だと思うが個人差はあるんだろうな


File::options().read(true).create(true).open("foo.txt”);

これを書くときにリードがtrueだな、createもtrueだな、そしてファイル名はfoo.txtだと言う思考順序で
コード書くとは思えないんですよ常識的に

145デフォルトの名無しさん2021/11/26(金) 12:29:19.27ID:kuMbCEJE
これが美しいと言う人はそれこそ逆ポーランド次元から来た異次元人だと思うよ

146デフォルトの名無しさん2021/11/26(金) 12:40:54.22ID:R0yJ4Kup
なかなか極端な例を出してきたな……

147デフォルトの名無しさん2021/11/26(金) 12:43:09.59ID:GoGODfBQ
おまいら日本語否定ですか。


>>144は設計が悪いんじゃない?

File::options().readwrite().newfile().open("foo.txt”);

なら自然だろ。
>>144

148デフォルトの名無しさん2021/11/26(金) 12:51:53.22ID:kuMbCEJE
逆ポーランド人現る

149デフォルトの名無しさん2021/11/26(金) 12:53:26.61ID:kuMbCEJE
ファイルを開こうと思うときにoptions型から思考がスタートする人は天才なんだろうな
それか飼いならされた人

150デフォルトの名無しさん2021/11/26(金) 12:57:20.12ID:kuMbCEJE
言語否定じゃなくてライブラリ設計がおかしい
実用無視の人が設計するとこうなる

151デフォルトの名無しさん2021/11/26(金) 12:58:29.05ID:Q6WyUjPa
File::open_with_options("foo.txt", &OpenOptions::new().read(true).create(true));

どっちが良いとか悪いとかじゃないと思うがなあ

152デフォルトの名無しさん2021/11/26(金) 13:13:18.47ID:kuMbCEJE
美しくないだろ普通に

153デフォルトの名無しさん2021/11/26(金) 13:13:45.37ID:HMe+psgI
OpenOptionsって名前で明らかに「ファイル開く時のオプションですよ」って名前なのにファイル開く操作まで持ってるから気持ち悪いんだよな
同じモジュールでディレクトリはDirBuilderとかあるんだから普通にFileBuilderとかにすりゃええやんとか思っちゃうけどなんか理由があったんかね

154デフォルトの名無しさん2021/11/26(金) 13:23:36.09ID:kuMbCEJE
確かに他だったらoptionのインスタンスを作ってopenに食わせる感じだな
それもどうかと思うけど
ほぼ定数みたいなものをわざわざ作って食わせるなんて

155デフォルトの名無しさん2021/11/26(金) 14:04:50.29ID:TIzT5fn9
慣れない人にとっては分かりにくいAPIにならざるを得ないのは確か

ただ他の言語でオプション引数やオーバーロードが2桁あるのが当たり前になってるようなライブラリを見るとそれぞれ一長一短あるなとは思う

156デフォルトの名無しさん2021/11/26(金) 14:15:29.08ID:Q6WyUjPa
>>154
associated constくらい用意してもらってもいいかもね

157デフォルトの名無しさん2021/11/26(金) 14:20:28.16ID:Ye0bskEh
>>153
OpenOptionsはrust1.0以前からあるものなのでその頃はビルダーのイディオムがなかったのだと思う
DirBuilderはrust1.6で追加されたものなので比較的新しい

158デフォルトの名無しさん2021/11/26(金) 14:57:24.65ID:AxmLr4ZJ
> 通常のCのオープン関数のほうが100倍キレイで簡潔で合理的

さっぱりわからんけどw
別に
File::options().readwrite().newfile().open("foo.txt”);
がいいとも悪いとも思わんし
cのopenがいいとも悪いとも思わん
どんな素晴らしいopen見せてくれるのかと思ったらガッカリした

159デフォルトの名無しさん2021/11/26(金) 15:03:20.08ID:BGloBCeB
OpenOptionsが分かりにくいってのはそのとおりだと思うし、実際みんなそう思ってるみたいで
ちょうどFile::optionsにするRFCが通るところだよ

160デフォルトの名無しさん2021/11/26(金) 16:18:02.52ID:Ye0bskEh
>>159
stabilizeのPRが10日前に取り込まれたから1月にはリリースされそう

161デフォルトの名無しさん2021/11/26(金) 18:16:06.66ID:kuMbCEJE
>>158
FILE * fopen(const char * filename, const char * mode);

こっちの方が100倍良い

162デフォルトの名無しさん2021/11/26(金) 19:18:40.42ID:wVYXipKz
>>161
それはfopenの仕様(引数の意味とか)を知っているのが前提だからなぁ。
filenameとmodeの順番を間違えたら読み間違える。
メソッドチェーンと比較するなら名前付き引数のメソッド呼び出しじゃない?
あるいはインテリセンス環境下という条件付きか。

163デフォルトの名無しさん2021/11/26(金) 19:21:46.75ID:Hq7eoo6P
>>161
ほんそれ

164デフォルトの名無しさん2021/11/26(金) 19:26:21.35ID:kuMbCEJE
仮想のコードで例が適切かどうかわからないけど

File::options().readwrite().newfile().read().open("foo.txt”)

と書いて直後で書き込めねえええええよと叫ぶよりfopenの方がいいだろ;

165デフォルトの名無しさん2021/11/26(金) 19:37:54.04ID:kuMbCEJE
あ、ミスった


それはさておき例のメソッドチェーン見ても瞬時に不安しかよぎらない

readwrite() が中で read(true).write(true) してるとして
readonly() が中でread(true)しかしてないんじゃないかとか不安

166デフォルトの名無しさん2021/11/26(金) 19:47:03.96ID:AxmLr4ZJ
>>162
> 名前付き引数のメソッド呼び出しじゃない?

俺も最初はそう言う話が出てくるのかとおもったら
cのopenを有りがたがってる奴が出てきて呆れた

167デフォルトの名無しさん2021/11/26(金) 20:09:04.42ID:XtGzaRsE
>>134
メソッドチェーンと関数チェーン|パイプラインが区別できてないんでは?
メソッドチェーンってレシーバの記述を省略できるとか文の数が減るとかでしかないでしょ。

168デフォルトの名無しさん2021/11/26(金) 20:37:35.34ID:kuMbCEJE
>>166
fopenとゴミみたいなメソッドチェーン
どっちがバグの温床だ?

169デフォルトの名無しさん2021/11/26(金) 20:42:02.78ID:kuMbCEJE
cのfopenはメソッドチェーンより簡潔だ

本当は他の言語のenumでいいんだけど

Open("rust.txt",FileMode.Open, FileAccess.Read)
これでバグは出ない

170デフォルトの名無しさん2021/11/26(金) 20:55:25.49ID:R0yJ4Kup
そんなに変わらへんやん、むしろuseで引き込む名前が増えて美しくないやん

171デフォルトの名無しさん2021/11/26(金) 21:02:27.39ID:Ye0bskEh
foo(true, false, true, false) や foo(None, None, None, Some(true)) みたいな呼び出しよりは100倍マシ

172デフォルトの名無しさん2021/11/26(金) 22:47:08.22ID:r6ugNRE0
ところでreadwrite()とかnewfile()ってなんですか?

173デフォルトの名無しさん2021/11/27(土) 00:09:21.90ID:riEP2Tv6
OpenOptionsの名称問題はともかく
なぜメソッドをチェーンさせているかというと理由は明白で
OpenOptionsExtトレイトをuseすると使えメソッドが拡張されて.mode()などが使えるようになるからだよ

174デフォルトの名無しさん2021/11/27(土) 00:15:29.99ID:4eTYjVC9
パイプ演算子は |> いつ実装されるの?

175デフォルトの名無しさん2021/11/27(土) 00:19:05.68ID:L+2AsAAt
どうせ上のtimes()トレイト君でしょ

176デフォルトの名無しさん2021/11/27(土) 00:42:49.16ID:w5eY7K13
チェーンの話なら、出来るだけチェーン派が多いけど.NETのLINQみたいになったら嫌?
それとも歓迎?LINQ形式のほうが分かりやすい。前の高階関数の話もそうだけど…
OpenOptionsはなんでもかんでもトレイトの弊害の気もする
articles =
  from a in articles
  orderby a.published descending
  select new article_st;
https://github.com/StardustDL/Linq-in-Rust
let e: Vec<i32> = linq!(from p in x.clone(), where p <= &5, orderby -p, select p * 2).collect();
このプロジェクトはcloneしてしまうところがダサいが、MSが参画しているということはありうるわけで

177デフォルトの名無しさん2021/11/27(土) 00:54:31.43ID:tWlgYd9Y
>>173
元がこうだもんな
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
そしてunix以外にも対応するために
std::os::unix::fs::OpenOptionsExtへ分けたのだろう
このメソッドチェーンビルダー方式以外のAPIでは詰む

178デフォルトの名無しさん2021/11/27(土) 05:50:15.37ID:IOkCeWcH
>>176
LINQはSQL風になる糖衣構文だからちょっと違うんちゃう。Rustに導入されても他の世界感と異質だし……。
個人的にはあれがSQL屋以外に直感的とは思えないw

179デフォルトの名無しさん2021/11/27(土) 09:55:26.18ID:sBo289Q7
>>174
rustは第一引数がselfの場合にメソッドのレシーバーになるのだから、実質パイプライン

180デフォルトの名無しさん2021/11/27(土) 11:01:40.71ID:kX7QbhiL
それはElixirと同じ「なんちゃってパイプライン」でメソッドチェーンが実現できるというだけでは。
ここで欲しいと言われているのは大元のF#のように自由関数やその部分適用が使えるパイプラインのことだろう。

181デフォルトの名無しさん2021/11/27(土) 12:26:31.88ID:Xdw8IP3R
自由関数?

182デフォルトの名無しさん2021/11/27(土) 14:14:35.41ID:A1VfIYPt
第一引数がselfとかじゃないやつのことじゃね

183デフォルトの名無しさん2021/11/27(土) 15:58:50.40ID:lc2cVbH3
自由関数ってなんだっけ?
自由変数ならわかるんだけど

184デフォルトの名無しさん2021/11/27(土) 15:59:45.03ID:Xdw8IP3R
定義を示してほしいわな
F#界隈にもRust界隈にも無い用語だし

185デフォルトの名無しさん2021/11/27(土) 16:36:46.11ID:kX7QbhiL
何気なく使ってたけど調べてみたらC++用語だったか。しかも日本じゃ「フリー関数」という表記の方が一般的なんだな。
メンバー関数(メソッド)ではない素の関数ということで。

186デフォルトの名無しさん2021/11/27(土) 17:08:07.51ID:FtAU5QYE
その意味ならElixirは自由関数も部分適用も使えると思うが・・・

187デフォルトの名無しさん2021/11/27(土) 17:20:05.91ID:kX7QbhiL
そっちか。
Elixirのパイプラインの使用例でよく見る形式が部分適用とは違うんで使えないものと思っていた。すまん。
部分適用は別の表記になるんだな。

188デフォルトの名無しさん2021/11/27(土) 17:59:12.10ID:g2vJAoph
C++でもフリー関数と言われたら free() のこと思い浮かべそうだが

189デフォルトの名無しさん2021/11/27(土) 18:21:56.04ID:molZfSEM
>>178
そうは言っても現状の下のこれが直感的に分かり易いとは思えないけど、、LINQはSQLとは関係ないよ。
whereとかselectがそれに見えるけど、言語的には直行性を高めた統合クエリなだけ
let mut y: Vec<i32> = x.clone().filter(|p| p <= &5).collect();
y.sort_by_key(|t| -t);
let y: Vec<i32> = y.into_iter().map(|t| t * 2).collect();

190デフォルトの名無しさん2021/11/27(土) 19:30:03.08ID:tWlgYd9Y
>>189
どこが見にくいのか具体的に教えて
use itertools::Itertools;
let y: Vec<i32> = x
 .filter(|p| p <= &5)
 .sorted_by_key(|t| -t)
 .map(|t| t * 2)
 .collect();

191デフォルトの名無しさん2021/11/27(土) 21:12:33.33ID:VfaT4D+K
>>185
> 何気なく使ってたけど調べてみたらC++用語だったか

どこの世界に非メンバ関数をフリー関数という馬鹿がいるのか詳しく
CかC++の規格のどこを参照すれば定義されているのか詳しく

192デフォルトの名無しさん2021/11/27(土) 21:19:49.42ID:w2+KtZN6

193デフォルトの名無しさん2021/11/27(土) 21:31:03.67ID:w2+KtZN6
Herb Sutterという馬鹿も使ってるな。
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4165.pdf

194デフォルトの名無しさん2021/11/27(土) 21:39:57.32ID:VfaT4D+K
規格の上ではまだ見つけられないが
https://timsong-cpp.github.io/cppwp/n3337/over.match.oper#tab:over.rel.op.func
member function
non-member function
という当然の名称が出てきている
日本語版の規格分かる人「フリー関数」とやらを引用してくだしあ

195デフォルトの名無しさん2021/11/27(土) 21:43:56.78ID:w2+KtZN6
規格で定義された用語というより業界用語的なもんでないの
https://github.com/cpprefjp/site/issues/171

196デフォルトの名無しさん2021/11/27(土) 21:44:30.32ID:lc2cVbH3
馬鹿っていちいち言うなよ
素直になれや

197デフォルトの名無しさん2021/11/27(土) 22:07:33.35ID:tWlgYd9Y
その「フリー関数」とはクラスのメンバー関数ではない非メンバー関数として
クラスのないRustではその非メンバー関数の定義はどうなるの?

例えば以下のprint_all()は適当に作ったトレイトPrintAllのメンバーかもしれないけど
現実には('a'..='z').print_all();が動作してしまうわけで『誰のメンバー関数』なの?それとも非メンバー関数?
trait PrintAll<T> {
 fn print_all(self);
}
impl<I: Iterator<Item=T>, T: Display> PrintAll<T> for I {
 fn print_all(self: I) {
  self.for_each(|x| println!("{}", x));
 }
}

198デフォルトの名無しさん2021/11/27(土) 22:20:27.30ID:w2+KtZN6
第一引数がselfである関数(メソッド)を自由関数として呼び出すことはできるけどその逆は真ではないってことじゃないかな。
https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax

199デフォルトの名無しさん2021/11/27(土) 22:24:30.93ID:dpgg2nfE
メソッド呼び出しできない関数は「フリー関数」ってことでええんちゃう?
非メンバ関数って呼ぶほうが断然一般的だとは思うが

200デフォルトの名無しさん2021/11/27(土) 22:47:33.66ID:riEP2Tv6
>>197
selfがIteratorだからクラス志向だとprint_all()はIteratorクラスのメンバーかな
しかしそのPrintAllはIteratorを継承してないから難しい

201デフォルトの名無しさん2021/11/27(土) 23:15:00.42ID:udgmz45E
https://dev.to/mindflavor/rust-builder-pattern-with-types-3chf
この手のPhantomDataとジェネリクス使って特定の条件満たした状態じゃないとbuildとかのメソッドが実装されないようにしたりしたビルダーパターンってここの人たちはどう思ってる?

説明だけ見るとめっちゃ良いやん!って思うけどいざ自分で書くとメリットに対して無駄に複雑&使う側としてもエラーが見にくいとかなんか微妙に感じちゃう

202デフォルトの名無しさん2021/11/28(日) 00:27:08.53ID:j8Nrs0jp
>>200
例えばこのように任意の実装が出来るからprint_all()はIteratorのメンバーではなくあくまでもPrintAllのメンバー
struct V<T>(Vec<T>);
impl<T: Display> PrintAll<T> for V<T> {
 fn print_all(self) {
  self.0.into_iter().for_each(|x| println!("{}", x));
 }
}

203デフォルトの名無しさん2021/11/28(日) 00:30:34.72ID:Fw4ypgsa
重要なのはフリー関数の定義じゃなくてパイプライン演算子の適用範囲だぞ

204デフォルトの名無しさん2021/11/28(日) 00:54:44.73ID:j8Nrs0jp
>>201
長くて斜め読みしかしていないがもっとわかりやすく示すとこういうことか

まず状態を示すダミーな型を作っておく
trait State {}
impl State for ToDo {}
impl State for Done {}
#[derive(Debug)]
struct ToDo;
#[derive(Debug)]
struct Done;

次にビルダーの構造体にダミーな型も収容する (サイズはゼロ)
type PD<T> = std::marker::PhantomData<T>;
#[derive(Debug)]
struct Builder<SetA: State, SetB: State> {
 a: i32,
 b: i32,
 _a: PD<SetA>,
 _b: PD<SetB>,
}
つまり変数aがセットされたか否かの状態をダミーな_aの型で示す
(つづく)

205デフォルトの名無しさん2021/11/28(日) 00:58:02.64ID:j8Nrs0jp
>>204の続き
初期値ToDoで開始してセットされたらDoneに変える
impl<SetA: State, SetB: State> Builder<SetA, SetB> {
 fn new() -> Builder<ToDo, ToDo> {
  Builder { a: 0, b: 0, _a: PD {}, _b: PD {}, }
 }
 fn set_a(self, a: i32) -> Builder<Done, SetB> {
  Builder { a, b: self.b, _a: PD {}, _b: PD {}, }
 }
 fn set_b(self, b: i32) -> Builder<SetA, Done> {
  Builder { a: self.a, b, _a: PD {}, _b: PD {}, }
 }
}

全部がDoneになった時だけ実行可能にしておく
impl Builder<Done, Done> {
 fn execute(&self) {
  println!("OK: {:?}", self);
 }
}

最初の呼び出しをわかりやすく用
fn new_builder() -> Builder<ToDo, ToDo> {
 Builder::<ToDo, ToDo>::new()
}

あとは両方がセットされると実行できる
fn main() {
 new_builder().set_a(123).set_b(456).execute();
}
片方でもセットを忘れるとコンパイル時にexecute()が解決できず失敗する
自分でこのコードを毎回間違えずに書くのは面倒なのでマクロ化されるなら採用

206デフォルトの名無しさん2021/11/28(日) 01:06:31.53ID:eXqoW6w6
またチラ裏コードの垂れ流し
いい加減やめてほしい

207デフォルトの名無しさん2021/11/28(日) 02:33:07.17ID:ZOlCZyFx
>>201
こういうのは手書きするのではなくて derive で良い感じに実装してほしい
あとrustdocの出力がごちゃつきそうなのが気になる

208デフォルトの名無しさん2021/11/28(日) 02:38:47.39ID:D4pWSHhU
自己満足コード見せられても困るよな

209デフォルトの名無しさん2021/11/28(日) 02:48:11.47ID:Fw4ypgsa
config部分が静的に決まってるならいいけど
UIやコマンドラインから動的にconfigしたい場合Builder traitを用意してtrait objectとして持ち回して
.execute()するためにdowncastする必要が……とかで二度手間になりそう

210デフォルトの名無しさん2021/11/28(日) 02:53:52.09ID:ghhRE59c
>>201のコードがいいと感じる感性が理解できないよ

211デフォルトの名無しさん2021/11/28(日) 10:39:31.01ID:XbegH2kB
>>201
難しい話をすると
ビルダはディレクタに対して抽象化されており
一個のディレクタが複数のビルダをケアできることを考えると
必須パラメータというのをビルダ実装ごとに準備するなら
ビルダというインタフェースがディレクタに対して実質破綻してると思う
でも
ビルダインタフェースが正しい呼び出し順を想定してたりするのをアリとするなら
必須パラメータも同じように勝手に想定しておいて
使う側にはドキュメントなりなんなりで勝手に指示だしとけば十分とも思う
そんで
呼び出し順や必須か否かに想定を置きたくない
呼び出し側に完全な自由度を与えたビルダインタフェースを提供したいなら
インタフェース Fooビルダ {Fooビルダ a(); Fooビルダ b();}
クラス 実際のビルダ implements Fooビルダ {
Foo(必須な何か x) {略} // コンストラクタで与えるとか
Fooビルダ 必須なc() {略} /* 実際のビルダ固有のメソッドとして与えて
new 実際のビルダ().必須なc().a() などと呼ぶか
Fooビルダ a() {略}
Fooビルダ b() {略}
Foo create() {略}
}
のようにして、ビルダインタフェース側だけはクリーンに守っておけばスッキリかも?
元のURLにあるように何が必須かをパラメータ化したいという欲求は解消してないのは認める

212デフォルトの名無しさん2021/11/28(日) 11:48:41.93ID:sDAG0wCq
インタフェースとかクラスとか意味不明すぎ

213デフォルトの名無しさん2021/11/28(日) 23:35:20.49ID:Fzo1fdIE
ここまで意味不明な文章書けるのって逆に凄いよ
このレベルは久々に見たわ

214デフォルトの名無しさん2021/11/29(月) 01:53:08.06ID:zo5XubVi
Javaコードの識別子の部分を日本語で書いて
GoFのオリジナルのBuilderパターンを説明しただけっぽい

なんでRustスレでそんな話をしたのかだけは完全に謎だが……

215デフォルトの名無しさん2021/11/29(月) 02:06:35.83ID:27e/xIh/
普通のBuilderであまり困ったことないからなあ

操作によって遷移していく状態があって、状態ごとに可能な操作が違う(呼び出せるメソッドが違う)とかなら意味あると思う(Socketのbind->accept->read/writeみたいな)
ただこういうものはもはやBuilderと呼ぶべきものではないと思う

216デフォルトの名無しさん2021/11/29(月) 09:45:31.17ID:3xWgo/Oc
それはStateパターンでしょ

217デフォルトの名無しさん2021/11/29(月) 15:25:28.77ID:aqqw7fQi
https://play.rust-lang.org/?version=stable&;mode=debug&edition=2021&gist=ebfd22dd62614e127bb3dbf0e57e5651
sもmutにしてDerefMutもimplしてるのになんでgの方は通らないんでしょうか?

218デフォルトの名無しさん2021/11/29(月) 16:49:12.44ID:4MgUQE5v
>>217
もっと単純に let z: *mut i8 = *s; も通らないので
これはDerefMutの条件であるmutable contextを満たしてないのではないか
そしてもちろん let z: &mut i8 = *s; は通るし **s = 88; も通るからDerefMut自体は機能している

219デフォルトの名無しさん2021/11/29(月) 18:03:30.09ID:3r4jR24z
PR出てるけどどうなるかわからない
https://github.com/rust-lang/rust/pull/86647

現状は
let s = &mut *s;
g(*s);
するか
g(&mut **s);
するか

220デフォルトの名無しさん2021/11/29(月) 18:58:43.82ID:Y4F1AeLY
>>218>>219
おお、そのものズバリが
あざます!

221デフォルトの名無しさん2021/11/30(火) 18:31:42.77ID:8WvE/rry
ifの閉じカッコにセミコロンが必要となる条件を教えてください
以下のプログラムはそれが足りないと指摘されてコンパイルエラーとなり
セミコロンを付けると通って動作するのですがどういう原理なのでしょうか?
fn main() {
 for line in BufReader::new(io::stdin()).lines() {
  let line = line.unwrap();
  if let [first, second, rest] = line.splitn(3, ' ').collect::<ArrayVec<_, 3>>()[..] {
   println!("{}:{}:{}", first, second, rest);
  }
 }
}

222デフォルトの名無しさん2021/11/30(火) 18:58:54.86ID:ZW4IpnTF
戻り値?

223デフォルトの名無しさん2021/11/30(火) 20:27:35.13ID:s7fhQ2Tk
ブロック式最後の式の値は、ブロック式の値として返るので drop されるタイミングがブロックの末尾よりも後の箇所になるということかな
for のブロックは値を返さないけど、ブロック式と同じ扱いをされているっぽい
https://play.rust-lang.org/?version=stable&;mode=debug&edition=2021&gist=b5639623c9a0dff8426f1d38b7123fdc

224デフォルトの名無しさん2021/11/30(火) 21:12:32.45ID:8WvE/rry
>>223
>> ブロック式最後の式の値は、ブロック式の値として返るので

もちろんおっしゃる通りでその例でも>>221の例でもif式の値は明瞭に()ですね

>> drop されるタイミングがブロックの末尾よりも後の箇所になるということかな

ブロック式の値として返るのは()ですから変数lineのdropタイミングが後にはならないように思うのですがどうなのでしょう?

225デフォルトの名無しさん2021/11/30(火) 21:32:53.10ID:hx6pGpzB
help: consider adding semicolon after the expression so its temporaries are dropped sooner, before the local variables declared by the block are dropped

↑エラーメッセージに理由書いてるよ

226デフォルトの名無しさん2021/11/30(火) 21:55:20.40ID:8WvE/rry
>>225
そのエラーメッセージでは理由になっていないのではないでしょうか?

例えば(for文を使わない)>>223の以下の部分を
if let [_first, _second, _rest] = line.splitn(3, ' ').collect::<ArrayVec<_, 3>>()[..] {}

このように2行へ書き換えても同じくセミコロンを付けろエラーとなりますが
let x = line.splitn(3, ' ');
if let [_first, _second, _rest] = x.collect::<ArrayVec<_, 3>>()[..] {}

このように2行へ書き換えるとコンパイルが通ります
let x = line.splitn(3, ' ').collect::<ArrayVec<_, 3>>();
if let [_first, _second, _rest] = x[..] {}

この差をどう見るのか教えていただけますでしょうか

227デフォルトの名無しさん2021/11/30(火) 22:02:05.25ID:s7fhQ2Tk
>>224
・lineの寿命はif-let式の寿命と一致する
・ブロックの最後の文の寿命はブロックを囲む文の寿命と一致する
という仕様になっていると思われる
型は関係なくてブロック内の最後の式か否かが重要

228デフォルトの名無しさん2021/11/30(火) 22:26:55.08ID:hx6pGpzB
>>226
>このように2行へ書き換えるとコンパイルが通ります
>let x = line.splitn(3, ' ').collect::<ArrayVec<_, 3>>();

line.splitnでborrowしたものを使ってるtemporaryは
let xで受けたタイミングでtemporaryじゃなくなる
(エラーメッセージにあるdropped soonerの状態になってる)

if式がブロックの最後の式でそのif式の一部がborrowを使ってるtemporary
セミコロンがないとtemporaryが解放される前にローカル変数のlineが解放されるからライフタイムのエラー

そのうち修正されるかもしれないけど今はそういう動きってこと

229デフォルトの名無しさん2021/11/30(火) 22:31:28.50ID:hx6pGpzB
>>226
>let x = line.splitn(3, ' ');
>if let [_first, _second, _rest] = x.collect::<ArrayVec<_, 3>>()[..] {}

230デフォルトの名無しさん2021/11/30(火) 22:35:06.87ID:hx6pGpzB
すまん、投稿ミス。

値を返したいときはセミコロンを追加するだけじゃだめだから
一旦変数で受けてからその変数をブロックの最後に書く

231デフォルトの名無しさん2021/11/30(火) 22:39:09.24ID:8WvE/rry
ふむむ
lineがヒープにあると以下の2行だけでセミコロン付けろエラーになりますね
let line = String::from("A B C D E");
if let [_first, _second, _rest] = line.splitn(3, ' ').collect::<ArrayVec<_, 3>>()[..] {}

このif let文を例えば以下のように変えるとセミコロンを付けなくても通るのはどうしてでしょう?
if let Some(_s) = line.get(3..6) {}

232デフォルトの名無しさん2021/11/30(火) 22:41:34.40ID:rIKeeiBO
なんでセミコロン付けると一時オブジェクトの寿命変わるんだって思ったけどそういえばC++にもそんな仕様あったな……
完全式じゃなくて戻り値に使うから破棄されないってことか

233デフォルトの名無しさん2021/11/30(火) 23:55:05.80ID:Y6JwF3m3
>>230
ブロックの最後で返す値は変数に入れなくても複雑な式でも大丈夫ですよ

234デフォルトの名無しさん2021/12/01(水) 12:41:12.28ID:KNT1MQhQ
なんでBufReadトレイトはあるのにBufWriteトレイトは無いんですか?

235デフォルトの名無しさん2021/12/01(水) 13:25:08.66ID:2cjkBPbo
>>231
詳しく知りたければまずはここ↓だけど
https://doc.rust-lang.org/reference/destructors.html

言語自体をいじりたいわけじゃなければ
あんまり深追いしても役に立たないよ

236デフォルトの名無しさん2021/12/01(水) 16:06:22.55ID:oI4zTDt2
>>234
BufReadはReadに対して追加の機能(行単位の読み込みなど)があるけど
Writeに対して追加すべき機能がないからBufWriteは存在しないのではないかと思われる

237デフォルトの名無しさん2021/12/01(水) 21:58:24.00ID:QwFnQ8Qa
flushしなけりゃ下のレイヤのどこかで勝手にバッファリングされることがほとんどだから用意する意味がないんだろな。

238デフォルトの名無しさん2021/12/01(水) 23:34:44.63ID:hYYowF9a
>>237
いやBufWriteトレイトが存在しないだけであってBufWriterはちゃんとある
そしてBufWriterがバッファリングする最後の要
誰かが勝手にバッファリングしてくれることはない
例えば何行もファイルに書き込む時にBufWriter使わずに各行毎にwriteしてたら遅くなる

239デフォルトの名無しさん2021/12/03(金) 14:04:46.92ID:xjf4hyRh
https://crates.io/crates/rust-script
とか
https://crates.io/crates/runner
みたいなの使ってる人おる?

これ使うくらいならLL使うとは思うが

240デフォルトの名無しさん2021/12/03(金) 14:45:17.46ID:RidNMi7I
REPL的にコードスニペットの実行確認するために使ったりはできるのかな
今はplaygroundで事足りているが

241デフォルトの名無しさん2021/12/04(土) 15:22:12.31ID:f29/w5s1
Read::read_to_end()に空のVecを渡した時に戻り値のusizeとVecのlen()が違う値になる事って有り得ますか?

242デフォルトの名無しさん2021/12/04(土) 23:32:14.41ID:VZLpyp2B
同じと思う
let file_size = file.metadata().map(|m| m.len())?;
let file_pos_before = file.stream_position()?;
let read_buf_size_before = read_buf.len();
このようなfileとread_bufがある任意の状況で
let read_size = file.read_to_end(&mut read_buf)?;
とread_to_end()すると以下が常に成り立っていると思われる
assert_eq!(read_buf_size_before + read_size, read_buf.len());
assert_eq!(file_pos_before + read_size as u64, file_size);

243デフォルトの名無しさん2021/12/05(日) 23:43:02.39ID:+2NbegRW
> loop式はbreakで指定した値を返せるのに
> なぜwhile式やfor式は値を返せないの?
> Option型にしてbreakで値を指定した時だけSome(値)としてそれ以外はNoneとすれば便利なのに

そのloopと組み合わせればよい
(例)
let r = 'result: loop {
 for x in 1..100 {
  for y in 1..100 {
   if x * y > 1234 {
     break 'result Some((x, y));
   }
  }
 }
 break 'result None;
};
assert_eq!(r, Some((13, 95)));

244デフォルトの名無しさん2021/12/06(月) 12:54:15.14ID:BduPW1Ae
>>243
forよりイテレータを繋げた方が単純でわかりやすいよ!と言おうとしたら
let r = (1..100)
 .map(|x| (1..100)
  .map(|y| (x, y))
  .find(|(x, y)| x * y > 1234)
 )
 .find(|o| o.is_some())
 .map(|oo| oo.unwrap());
assert_eq!(r, Some((13, 95)));
むしろ複雑でわかりにくくなってしまったw
まさかの>>243のダミーloop使用がベストアンサーなのか!?

245デフォルトの名無しさん2021/12/06(月) 13:12:38.43ID:PE/XVSQC
>>244
flat_mapを使えば良い
let r = (1..100).flat_map(¦x¦ (1..100).map(¦y¦ (x, y))).find(¦(x, y)¦ x * y > 1234);

246デフォルトの名無しさん2021/12/06(月) 13:28:57.99ID:GjZweGXf
どれもこれも分かりやすいとは思えない

247デフォルトの名無しさん2021/12/06(月) 15:59:22.06ID:BduPW1Ae
結局見やすくこう書けるといいんだよね
let r = pair(1..100, 1..100).find(|(x, y)| x * y > 1234);
assert_eq!(r, Some((13, 95)));
これでassertも通ったけどyのイテレータとx自身の2ヶ所にCloneが必要となってしまった
避けられないような気がするけどどうでしょうか?
fn pair<IX: Iterator<Item=X>, IY: Iterator<Item=Y> + Clone, X, Y>(ix: IX, iy: IY) -> Pair<IX, IY, X, Y> {
 Pair { cur_ox: None, cur_iy: iy.clone(), ix: ix, iy: iy, }
}
struct Pair<IX: Iterator<Item=X>, IY: Iterator<Item=Y>, X, Y> {
 cur_ox: Option<X>, cur_iy: IY, ix: IX, iy: IY,
}
impl<IX: Iterator<Item=X>, IY: Iterator<Item=Y> + Clone, X: Clone, Y> Iterator for Pair<IX, IY, X, Y> {
 type Item = (X, Y);
 fn next(&mut self) -> Option<Self::Item> {
  loop {
    if let None = self.cur_ox {
     self.cur_ox = self.ix.next();
    }
    if let Some(ref x) = self.cur_ox {
     if let Some(y) = self.cur_iy.next() {
      break Some((x.clone(), y));
     } else {
      self.cur_ox = None;
      self.cur_iy = self.iy.clone();
      continue;
     }
    } else {
     break None;
    }
  }
 }
}

248デフォルトの名無しさん2021/12/06(月) 16:01:51.04ID:NQsvo9rr
最近知ったボクの大発見書いていい?
let a: Option<i32> = None;
これは
let a = None::<i32>;
と書ける
関数のパラメータとして渡そうとして
f(None)で怒られたとき
f(None::<i32>)として怒られない

しょうもないレス失礼いたしました

249デフォルトの名無しさん2021/12/06(月) 16:21:14.38ID:BduPW1Ae
>>248
曖昧性を確定させる::<型>の指定は色々なところで出てくるね
例えばcollect::<Vec<_>>()とか
ブロックやクロージャの返り値でOk::<(),std::io::Error>(())とか

250デフォルトの名無しさん2021/12/06(月) 16:35:36.71ID:McsJgKJD
>>247
itertoolsのcartesian_productがほぼそれ

251デフォルトの名無しさん2021/12/06(月) 17:07:16.47ID:+ZC47hZJ
iproduct!

252デフォルトの名無しさん2021/12/06(月) 17:09:45.91ID:Fu08U5Ef
>>248
型パラメータは Option のパラメータなので順当に考えれば Option::<i32>::None と書くべきだし実際にそれで通るんだけども、
歴史的経緯でバリアントにも付けられるようになってる。

短く書けるから習慣的にはバリアントに型を付けるほうが多いかな……?

253デフォルトの名無しさん2021/12/06(月) 17:31:38.25ID:BduPW1Ae
>>250
なるほど直積集合かぁ
同じくyのイテレータとxはCloneを要求してますね
fn cartesian_product<J>(self, other: J) -> Producfgt<Self, J::IntoIter>
where
 Self: Sized,
 Self::Item: Clone,
 J: IntoIterator,
 J::IntoIter: Clone,

254デフォルトの名無しさん2021/12/06(月) 20:06:32.13ID:NQsvo9rr
>>249
> Ok::<(),std::io::Error>(())とか

正直見たことなかったです

>>252
> 歴史的経緯でバリアントにも付けられるようになってる。

(´・∀・`)ヘー
そういうわけなんですね

255デフォルトの名無しさん2021/12/06(月) 21:47:08.33ID:BduPW1Ae
>>254
例えばlet x = spawn(async { ... });して裏で何か処理をやらせといた結果を
後でもしエラーが出ていたら進めちゃいけないタイミングでx.await?;で確認するわけだけど
spawnが返す型をxに律儀に記述するのは面倒なのでそこは略すとして
asyncブロック内で?とOk(())だけ書くとコンパイラが文句を言うので仕方なく記載

256デフォルトの名無しさん2021/12/06(月) 22:11:44.75ID:NQsvo9rr
なるほど勉強になりました

257デフォルトの名無しさん2021/12/07(火) 21:26:04.18ID:pFZAiCY5
12次元までならiproduct!が使える
use itertools::iproduct;
let r = iproduct!(1..100, 1..100).find(|(x, y)| x * y > 1234);
let r = (|| {
 for (x, y) in iproduct!(1..100, 1..100) {
  if x * y > 1234 {
   return Some((x, y));
  }
 }
 return None;
})();

258デフォルトの名無しさん2021/12/08(水) 14:18:48.01ID:6NuoEm2L
ARM版のWindowsでRustのコードを書くのってめんどくさいな
生のWindowsで使用する場合、VisualStudioに付属するx86用のリンカーが非推奨警告を無視すれば使えたものの、次期バージョンからx64専用になってしまうっぽい
一方、仮想環境等+VSCodeでは、RustAnalyzer等が機能せず苦労する・・・・
持ち運び用にケチってMacを買わなかったのが大問題だった、なんかいい方法ないのかな?そもそもARM Windowsで動くリンカーってVisualStudio付属のものしかないのかな?
ケチったって言ってもよくよく考えてみると大して金が浮いてもないし、変なもん買っちまった

259デフォルトの名無しさん2021/12/08(水) 14:36:22.94ID:W5vI+s6z
>>258
i686ターゲットのバイナリをバイナリ変換で動かしてるってこと?
aarch64-windowsターゲットとARM用のリンカ使えばネイティブのARMバイナリできるんじゃないかと思うけど

260デフォルトの名無しさん2021/12/08(水) 20:15:10.58ID:pzF9gjPk
バイナリバイナリルルルルルー。

261デフォルトの名無しさん2021/12/08(水) 21:25:01.32ID:t4Pzut9P
rustはどんどん新しい機能が追加されていくのはいいけど、
後方互換性を気にして過去に追加された「間違った」機能を削除するという
思い切ったこともやって欲しいな

これまでの言語は後方互換性にとらわれて滅茶苦茶になってるから

262デフォルトの名無しさん2021/12/08(水) 21:29:04.83ID:ff6DaDGr
>>261
C++かな?

263デフォルトの名無しさん2021/12/08(水) 21:44:15.05ID:tBq4QMAR
>>261
editionでは物足りない?

264デフォルトの名無しさん2021/12/08(水) 21:50:49.56ID:t8qOOWvR
実際2021editionではレンジパターンの ... が削除されて ..= に一本化された

265デフォルトの名無しさん2021/12/09(木) 08:53:14.94ID:sqaPNXyj
>>258
今どきDocker使うのはデフォだから何の問題もない、因みにRustAnalyzerも使える
使えないのは、復数のプロジェクトが見える状態にしてるから
今どき復数ウィンドウ立ち上げても何の問題もない、ルートフォルダを固有にしたら解決
つまり、調査不足が原因

266デフォルトの名無しさん2021/12/09(木) 10:59:17.60ID:4q0mFQ+L
ARM は安物のイメージがある。
WSL2, Linux, Docker, VSCode とか使えるのかな?

Mac も、M1 に変わったから

267デフォルトの名無しさん2021/12/09(木) 11:10:00.09ID:XwSSuf4e
原理的には ARM のほうがインテル系 (もはや AMD 系と呼ぶべきか) よりも高速化できる可能性があるとは言われている。
今以上に回路を細かくするのは無理というところまできてしまっているのでアーキテクチャのほうで見直しが必要なんだが
インテル系は互換性が足かせになってしまっていてあまり思い切ったことが出来ない。

現時点はインテル系向けにチューニングされたソフトウェア資産が多いから上手くいっているけど将来もそうとは限らない。

268デフォルトの名無しさん2021/12/09(木) 11:45:18.26ID:t4DQqTrM
>>267
スレチだけどその話の出展あったら教えてほしい

269デフォルトの名無しさん2021/12/09(木) 14:22:31.39ID:RSXecyhf
CISCRISCの話じゃなくてメモリモデルの話ならそうかなって思う
今のx64って実質中身RISCって聞いたことあるし
Rustで言うとx64では全部SeqCstとして扱われるみたいな話

270デフォルトの名無しさん2021/12/09(木) 17:42:03.96ID:VJ9QB09P
リソースの話だけなら命令デコーダーとか?
x86_64は拡張や互換性とか可変長命令だったりで無駄にトランジスタ消費するのが電力性能比的に足かせみたいな

271デフォルトの名無しさん2021/12/09(木) 20:39:08.00ID:0MvTGuxY
今どきのプロセッサだと分岐予測器やキャッシュが支配的でデコーダなんて誤差だと思う
あと可変長は命令側の帯域やキャッシュ効率が良くなるという面もあってRISC系でも採用してることが多い
結局両者とも長年の改善で似たようなとこに落ち着いてるわけで、ISAが違うからどうこうみたいな話は結構眉唾

272デフォルトの名無しさん2021/12/11(土) 19:08:58.23ID:oic9EtmK
こういうことをしたいのですがコンパイルエラーとなってしまいます
const DEFAULT_NAME: &str = "namae";
let arg1: Option<String> = std::env::args().nth(1);
let name: &str = arg1.map_or(DEFAULT_NAME, |s| s.as_str());
どう直せばよいでしょうか?

273デフォルトの名無しさん2021/12/11(土) 19:10:55.89ID:ZSpAs+oG
namaeじゃなくてnameな
aが余計
この程度の英語のスペル書けないとかプログラミング向いていないしやめた方がいいよ

274デフォルトの名無しさん2021/12/11(土) 19:21:25.94ID:UNEoSQah
自演ボケか?

275デフォルトの名無しさん2021/12/11(土) 19:35:01.57ID:K+rsGRUk
>>272
そのままだとarg1が消費されてなくなるのに参照だけ残ることになるからエラー
Stringで受ければいいよ
let name: String = arg1.unwrap_or(DEFAULT_NAME.to_string());

276デフォルトの名無しさん2021/12/11(土) 20:19:05.99ID:XRkKLs6o
>>273
すげーな。してはいけないレビューの典型例じゃねーか。
すげーな

277デフォルトの名無しさん2021/12/11(土) 20:24:40.06ID:Z1L5tslT
いやネタでしょ

278デフォルトの名無しさん2021/12/11(土) 20:29:51.18ID:/anFx7me
>>275
これだとarg1がSomeの時もto_string()が呼び出されて無駄なヒープアロケーションが走るのでunwrap_or_elseにすべき

279デフォルトの名無しさん2021/12/11(土) 22:35:07.46ID:oic9EtmK
みなさんありがとうございます
Stringにする方法は無事にこれで動きました
let name: String = arg1.unwrap_or_else(|| DEFAULT_NAME.to_string());
元の質問>>272のように&strにする方法は無いのでしょうか?
もし可能ならばto_string()のヒープアロケーションを減らせるかなという質問です

280デフォルトの名無しさん2021/12/11(土) 22:59:59.99ID:yVS9OnV5
>>279
Cowかな
let name: Cow<str> = arg1.map_or(Cow::Borrowed(DEFAULT_NAME), |s| Cow::Owned(s));

281デフォルトの名無しさん2021/12/11(土) 23:20:49.43ID:yVS9OnV5
場合によってはこれでもいいのかな?
let name: &str = &arg1.as_ref().map_or(DEFAULT_NAME, |s| s.as_str());

282デフォルトの名無しさん2021/12/11(土) 23:54:40.62ID:tYxQqCnY
>>281
それでもよいけど正解はシンプルなこれ
let name: &str = if let Some(ref arg1) = arg1 { arg1 } else { DEFAULT_NAME };
まずarg1を消費しないようにrefで受ける
2代目のarg1は&Stringなので自動的に&strへderefされる

283デフォルトの名無しさん2021/12/12(日) 02:10:02.51ID:h/Sb7JBW
1.40からas_derefっつうのがあるんだってさ
let name = arg1.as_deref().unwrap_or(DEFAULT_NAME);

でもコマンドライン引数の場合は消費しないメリットがほぼ無いのでCowのほうがいいかな

284デフォルトの名無しさん2021/12/12(日) 04:28:54.46ID:8d+idsXS
どの型で統一すべきかは
(1) その後に加工伸長などするならString (arg1をここで&strに統一するのは無駄)
(2) 参照するのみなら&str (DEFAULT_NAMEをここでto_stringするのは無駄)
(3) その後に判明する条件次第で両ケースありうるならCow (ただし常にCow利用はCowコストが無駄)
って感じ?

285デフォルトの名無しさん2021/12/12(日) 10:07:32.08ID:svMJrknn
おそらくその通りだけど、CLIツールの初回一回だけのアロケーションにそこまでこだわるのがそもそも無駄って気もする
ループ内とかでもなければ雑にString作っちゃっていいかもね

286デフォルトの名無しさん2021/12/12(日) 10:31:14.68ID:eE6Pv/WZ
んだ

287デフォルトの名無しさん2021/12/12(日) 10:46:59.45ID:8d+idsXS
>>285
今回のケースはそうだね
ただしヒープ割り当てをなるべく避ける様々な手法を把握しているか否かは色んな局面で効いてくるから
今回6通りも動くコード例が示されたことは多様に対応可能な柔軟性の良さかな
気にしなくても書けるし気にすれば効率を上げることができる点で

288デフォルトの名無しさん2021/12/12(日) 18:38:25.33ID:h/Sb7JBW
>>284
Cowと&strに揃える場合の一番の違いはライフタイム管理
Stringを&strにするとライフタイム管理がつきまとうから
すぐ使いきる場合以外はCowに比べてメンテナンスしにくいコードになる

289デフォルトの名無しさん2021/12/12(日) 18:59:43.58ID:3rjDzGgS
文字列についてはStringにするかCow<str>にするか迷うくらいならinternしちゃうのも手かと
どのライブラリが定番なのかよく知らないけど

290デフォルトの名無しさん2021/12/12(日) 19:49:57.76ID:be4Z/veb
>>281
> let name: &str = &arg1.as_ref().map_or(DEFAULT_NAME, |s| s.as_str());

それarg1の前の&は不要でこれで動く
let name: &str = arg1.as_ref().map_or(DEFAULT_NAME, |s| s.as_str());

さらにas_str()使うより短く書けて&**sで&strになる
let name: &str = arg1.as_ref().map_or(DEFAULT_NAME, |s| &**s);

さらに&Stringのsのままでもderefされるため大丈夫
let name: &str = arg1.as_ref().map_or(DEFAULT_NAME, |s| s);

クロージャが何もしてないからといって無くしてしまうとderefが効かず型不一致コンパイルエラー
× let name: &str = arg1.as_ref().unwrap_or(DEFAULT_NAME);

そこで明示的にderefしてやればよい
let name: &str = arg1.as_deref().unwrap_or(DEFAULT_NAME);

291デフォルトの名無しさん2021/12/13(月) 21:23:25.03ID:zBnuOauJ
ken okabeのqiitaの記事がまた炎上してるよ
mod_poppoにボコボコにされてる

292デフォルトの名無しさん2021/12/13(月) 22:30:34.09ID:i33Tname
あれ、Qiitaには垢バンされて投稿できないんじゃなかった?

293デフォルトの名無しさん2021/12/13(月) 23:00:30.90ID:Yx06Lw1d
ググってもよくわからないのですが、どういった方なんですか?

294デフォルトの名無しさん2021/12/13(月) 23:30:17.26ID:IeJGNs4K
盛大な時間の無駄になるだけなので調べてはいけない

295デフォルトの名無しさん2021/12/13(月) 23:59:51.20ID:mqpFvLOG
>>291
poppoとかいうやつも多様な定義や多様な解釈が存在している中で不要なイチャモンばかりだな
さらに冒頭のこれも

> JavaScriptで演算子オーバーロードを実現しようとするのは筋が悪い

たまたま例としてJavaScriptを用いているだけなのにそれすら理解できていない
okabeは使用言語と無関係に成り立つ話をしてるだろ

> reduceは二項演算ではなく三項演算として捉えるべき

これも些細なことであって例えばRustなら
fold()は『入力列・初期値・演算関数』の三項演算だけど
reduce()は『入力列・(初期値は入力列の先頭なので無指定)・演算関数』の二項演算

とはいえokabeの方もイテレータすら扱っていないからイマイチ

296デフォルトの名無しさん2021/12/14(火) 00:07:08.47ID:LYbWtya0
Rust関係ねーだろ
二度とその名前を口に出すな

297デフォルトの名無しさん2021/12/14(火) 10:41:11.49ID:QBQJlKEt
P2P方式の2D対戦ゲームを作りたいと考えています。
おすすめのゲームエンジンやライブラリはございますか?

298デフォルトの名無しさん2021/12/14(火) 11:46:02.04ID:mpAOsF0a
>>297
あくまでゲームを作ることが目的なんだったら普通にUnityとかでいいんじゃない?
どうしてもRust使いたいならサーバー側で使えばいい

299デフォルトの名無しさん2021/12/14(火) 12:45:44.37ID:QBQJlKEt
>>298
個人的にRustが好きなので技術向上のためにもRustで作りたいと考えています。
現在はAmethystとlibp2pを用いて開発しようと考えているのですが、如何せん知識が浅くこれで目的のものが作れるのか分かりません。
是非先人の知恵をお貸しください。
Rustでの開発にロミオとジュリエットの恋ほどの壁があるという場合は、大人しくC++かUnityで作成します・・・

300デフォルトの名無しさん2021/12/14(火) 13:10:49.68ID:+JRF3Q+g
そんだけの情報ではなんともいえん。

見通しが立たないものを試行錯誤で作る場合には
モジュールではなくレイヤで分割したほうがいいという考え方がある。
要するに機能不足でもバグだらけでもコードが整理されてなくてもいいからとにかく「動くもの」を作って
その上に足りないものをどんどん足していくという方法論だ。

よくわかってないなら小さいもので色々やってみて知識を積み重ねるべきで、
よくわからんまま目的に向かって邁進してもあんまり技術向上にはならんよ。

301デフォルトの名無しさん2021/12/14(火) 13:22:32.10ID:QBQJlKEt
>>300
ありがとうございます
色々試してみます

302デフォルトの名無しさん2021/12/14(火) 13:53:41.90ID:ZTFSAiNI
>>299
Amethystは開発中止になったから今からやるのは微妙かも
gamedev.rsに今アクティブなエンジンやゲームがスクショ付きで載ってるから
そこからイメージにあうものを探すといいかもしれない

303デフォルトの名無しさん2021/12/14(火) 15:30:19.02ID:QBQJlKEt
>>302
そうだったんですね・・・
時間は掛かるかもしれませんが、色んなものを試して自分に合う物を探すことにします

304デフォルトの名無しさん2021/12/15(水) 07:48:40.06ID:inpCEPk8
技術を高める目的なら windows-rs や wgpu-rs みたいな一段下から積み上げるのも楽しいよ。

ゲーム作る道のりは遠くなるけど、画面に三角形出したり、キーの入力受け付けたりするだけで達成感が出てくる。

305デフォルトの名無しさん2021/12/17(金) 12:43:03.76ID:jilrKB7M
https://forest-watch-impress-co-jp.cdn.ampproject.org/c/s/forest.watch.impress.co.jp/docs/serial/yajiuma/1374/986/amp.index.html
エディタ自体はvscodeに勝つの難しそうだがGPUIとやらが定番GUIフレームワークにならないか期待

306デフォルトの名無しさん2021/12/17(金) 16:39:33.05ID:6JlgT7vi
既出だったらすいません
前から疑問だったのですが、出力におけるprint!マクロのような入力用マクロが標準ライブラリに用意されていない理由ってなんですか?

307デフォルトの名無しさん2021/12/17(金) 18:11:01.90ID:tWB5K5S1
>>297
1対多で、broadcast するチャットルームのバックエンドなら、
Ruby on Rails 6 のAction Cable(WebSocket)が基本

JavaScript は、React, Phaser とか

【Rails】(送信時のリロード無し!)Action CableでSlack風チャットアプリを作成、2019/12


308デフォルトの名無しさん2021/12/17(金) 18:36:09.20ID:ePonqmC1

309デフォルトの名無しさん2021/12/17(金) 23:52:56.58ID:6JlgT7vi
>>308
熟読させていただきました。
私としてはたった数十行のコードであること且つ他のほとんどの言語に存在しているものなのであっても良いのかなと思ったのですが、Rustの基本理念を考えると慎重になる理由も理解出来ました。
Rustの経験が浅い私目線ではあまり腑に落ちませんでしたが、皆さんはどう考えていますか?

310デフォルトの名無しさん2021/12/18(土) 15:05:52.37ID:JzdvFl4u
熟読はしてないけど、外部ライブラリで簡単に実現可能であるなら
直感的には、本体メンテナの苦労を増やすほど価値があると思えないし別にいらんかな

こういうIOとかCLIプロンプトらへんの機能ってどうしても好みが分かれるというか、
ユースケースによって必要な機能がかなり違ってきちゃうと思うし

311デフォルトの名無しさん2021/12/18(土) 20:46:47.80ID:w6oxugk6
C++のiostreamが失敗作だから慎重になるのもわかる笑

312デフォルトの名無しさん2021/12/18(土) 23:17:58.09ID:SfwydFh9
>>306
C言語でのprintf相当はあるのにscanf相当がstdにないのはなぜか?ですね
逆になぜprintf相当がRustの標準ライブラリにあるのか?を考えてみると

(1) 読み書きの非対称性
人間が読むためにプログラムが書くことはエラー表示を含めて利用必須かつ頻出
一方で人間が書いたものをプログラムが読むことはレア
ファイルや通信相手への読み書きは各プロトコル/各API/シリアライズ等で対象外

(2) コンパイラサポート
print!やformat!等は頻出するので効率面からコンパイラサポートが効率的
実際にそれらが利用しているformat_args!はコンパイラ内蔵マクロ

(3) 標準ライブラリ採用
外部ライブラリで実現可能なものは採用しないが基本
今回はコンパイラ内蔵マクロだから採用

つまり出力は頻度と効率化で採用がクリアされたけど
入力は外部ライブラリで十分かなと

313デフォルトの名無しさん2021/12/19(日) 02:25:28.05ID:KXG/wmTu
しかし競プロでみんなproconioとかいう謎の専用ライブラリ使ってるの見た目悪すぎて笑える

314デフォルトの名無しさん2021/12/19(日) 04:21:35.56ID:1R2jF/rb
競プロ全然知らないけどstdinに入力数値がくるからか

| 入力は以下の形式で標準入力から数値が与えられる。
| a b c d e
| 積が奇数なら Odd と、 偶数なら Even と出力せよ。

標準ライブラリだけ使うと毎回こんなの書くのは面倒だもんな

| use std::io::{stdin, BufRead, BufReader};
| println!("{}", if BufReader::new(stdin()).lines().next().unwrap().unwrap().split(' ').any(|s| s.parse::<isize>().unwrap() & 1 == 0) { "Even" } else { "Odd" });

>>313
そのproconioを使うとこうなるようだ

| proconio::input! { v: [isize; 5] }
| println!("{}", if v.into_iter().any(|n| n & 1 == 0) { "Even" } else { "Odd" });

315デフォルトの名無しさん2021/12/19(日) 06:54:36.03ID:KXG/wmTu
>>314
ワンライナー大好きかよ

316デフォルトの名無しさん2021/12/19(日) 07:00:31.55ID:1R2jF/rb
>>315
マルチラインだと標準ライブラリだけでもわかりやすくなる?

317デフォルトの名無しさん2021/12/19(日) 08:28:47.39ID:KXG/wmTu
>>316
あいやごめん。proconioのところはどうあがいてもプロコン専用のproconioが一番見やすいよ。それ用に特化されたライブラリだし
俺が大好きかよって言ったのは
println!("{}", if v.into_iter().any(|n| n & 1 == 0) { "Even" } else { "Odd" });
の部分

318デフォルトの名無しさん2021/12/19(日) 09:08:15.26ID:1R2jF/rb
どの言語でも三項演算子(相当)はワンライナーで書くんじゃね?

319デフォルトの名無しさん2021/12/19(日) 09:36:51.21ID:Tv9xxy1h
見た目汚いなw

320デフォルトの名無しさん2021/12/19(日) 09:42:08.31ID:1R2jF/rb
これでいいかね?
println!("{}", if v.into_iter().any(|n| n & 1 == 0) {
 "Even"
} else {
 "Odd"
});

321デフォルトの名無しさん2021/12/19(日) 09:57:56.98ID:KXG/wmTu
俺ならこんな感じかなあ
俺は頭悪いから、途中結果に一つ一つ名前つけないとわかんなくなっちゃうわ
まあワンライナー見た時に「グエー」って思っただけだからごめん。「大好きかよ」とかいっておいてなんだけどあんま気にしないで

use proconio::input;

fn main() {
input!(v: [usize; 5]);
let is_even = v.iter().any(|x| x % 2 == 0);
let result = if is_even {
"Even"
} else {
"Odd"
};
println!("{}", result);
}

322デフォルトの名無しさん2021/12/19(日) 10:13:36.41ID:1R2jF/rb
>>321
なるほど
じゃあ最初の標準ライブラリのみはどのように分けるのかな
println!("{}", if BufReader::new(stdin()).lines().next().unwrap().unwrap().split(' ').any(|s| s.parse::<isize>().unwrap() & 1 == 0) { "Even" } else { "Odd" });

323デフォルトの名無しさん2021/12/19(日) 10:17:01.07ID:KXG/wmTu
>>322
proconio使うw
Rustで競プロするにはIOごときに専用ライブラリ使うことになってなんかなあって思うけど、そう思いながら使う

324デフォルトの名無しさん2021/12/19(日) 12:54:53.29ID:XhCh7cuL
>>315
ワンライナーやクロージャでまとめて書くと所有権やライフタイムの問題が出にくいんだよ
他の言語と違ってRustで適切に分割して読みやすく書くのは初心者には難しい

325デフォルトの名無しさん2021/12/19(日) 13:44:27.43ID:JD8Mu2Jr
わけわからんくてビビってたらよく見るとPythonスレじゃなかった

326デフォルトの名無しさん2021/12/19(日) 15:04:40.83ID:9UFbsF2U
rustfmt使うでしょ普通

327デフォルトの名無しさん2021/12/19(日) 21:36:12.89ID:1R2jF/rb
>>326
println全体が改行されてしまった

println!(
 "{}",
 if BufReader::new(stdin())
  .lines()
  .next()
  .unwrap()
  .unwrap()
  .split(' ')
  .any(|s| s.parse::<isize>().unwrap() & 1 == 0)
 {
  "Even"
 } else {
  "Odd"
 }
);

一方で分割するとこうなった

let cond = BufReader::new(stdin())
 .lines()
 .next()
 .unwrap()
 .unwrap()
 .split(' ')
 .any(|s| s.parse::<isize>().unwrap() & 1 == 0);
println!("{}", if cond { "Even" } else { "Odd" });

if式自体はワンライナーーで正解とrustfmtはおっしゃってる

328デフォルトの名無しさん2021/12/19(日) 21:50:26.03ID:gPlFWszB
ワンライナー云々はフォーマットの話ではないやろ

329デフォルトの名無しさん2021/12/19(日) 22:05:50.34ID:1R2jF/rb
例えば>>321がif式を5行に分割しているが
それもrustfmtにより1行に修正された

Rust標準ライブラリのソースでもワンライナー
bool.rs: if self { Some(t) } else { None }
result.rs: let n = if self.inner.is_some() { 1 } else { 0 };
time.rs: let prefix = if f.sign_plus() { "+" } else { "" };

>>328
では何の話かね?

330デフォルトの名無しさん2021/12/19(日) 22:37:44.04ID:D79ys1jH
構造と書式を区別できんのはヤバイで

331デフォルトの名無しさん2021/12/19(日) 23:10:30.41ID:ZhiL7Huf
心底どうでもいい。
保守性に貢献するどころかマイナスになるようなクソプライドコードの導入すんなよ。

332デフォルトの名無しさん2021/12/19(日) 23:14:48.39ID:4jRnwXL4
また性懲りもなくコードべたべた書いてんのか

333デフォルトの名無しさん2021/12/19(日) 23:21:45.51ID:cDs+Q4pL
rustfmtだから書式の話やで

334デフォルトの名無しさん2021/12/19(日) 23:25:17.24ID:/BRS7QS/
区別できなかったからrustfmtを持ち出したんやろ
どこに改行入れるべきかって話だと思ったんだろなww

335デフォルトの名無しさん2021/12/19(日) 23:41:46.15ID:1R2jF/rb
rustfmtを持ち出したのは俺じゃないぜ
あと今回のケースならここは分割するよな
let reader = BufReader::new(stdin());
let line = reader.lines().next().unwrap().unwrap();
let is_even = line.split(' ').any(|s| s.parse::<isize>().unwrap() & 1 == 0);

336デフォルトの名無しさん2021/12/19(日) 23:48:52.91ID:m2ZvKw+8
汚コード

337デフォルトの名無しさん2021/12/19(日) 23:59:56.43ID:cDs+Q4pL
問題文が>>314でこうなってるから
>> | 入力は以下の形式で標準入力から数値が与えられる。
>> | a b c d e

if let [a, b, c, d, e] = line
 .splitn(5, ' ')
 .map(|s| s.parse::<isize>().unwrap())
 .collect::<ArrayVec<_, 5>>()[..] {

あとこれでいい
let is_even = a & b & c & d & e & 1 == 0;

338デフォルトの名無しさん2021/12/20(月) 05:23:59.31ID:XPDM+Al+
そういえばいつの間にか
let variable = 3;
println!("{variable}");
みたいな書き方が出来るんだけどこれ前からだっけ?

339デフォルトの名無しさん2021/12/20(月) 05:50:08.07ID:MpI5dMic
>>338
それはまだnightlyだけですよ
来月の1.58からstableになって使えるようになる予定

340デフォルトの名無しさん2021/12/20(月) 11:31:40.46ID:vxPhPqzv
>>335
構造化の基本を学びましょう

341デフォルトの名無しさん2021/12/20(月) 18:38:24.90ID:+mZvzmRI
どちらのコードも正解

342デフォルトの名無しさん2021/12/20(月) 18:57:17.41ID:rubGoZ9q
コードに「間違い」はあっても「正解」はない

343デフォルトの名無しさん2021/12/20(月) 19:04:29.92ID:MpI5dMic
間違っているコードは出ていないような
問題視してる人は具体的に何を問題にしているの?

344デフォルトの名無しさん2021/12/20(月) 20:55:59.37ID:lwZpjeWf
アスぺ思考はこれだから

345デフォルトの名無しさん2021/12/21(火) 11:25:19.41ID:TTfv6HaA
https://doc.rust-jp.rs/book-ja/ch18-03-pattern-syntax.html#%E3%83%9E%E3%83%83%E3%83%81%E3%82%AC%E3%83%BC%E3%83%89%E3%81%A7%E8%BF%BD%E5%8A%A0%E3%81%AE%E6%9D%A1%E4%BB%B6%E5%BC%8F
ここの最後のところに

パターンと関わるマッチガードの優先度は、以下のように振る舞います:
(4 | 5 | 6) if y => ...
以下のようにではありません:
4 | 5 | (6 if y) => ...

とあるんですが、後者のようになってほしい場合は4|5と6 if yを別々に書くしか無いですか?

346デフォルトの名無しさん2021/12/21(火) 11:56:47.99ID:BV9oeByN
>>345
ガード構文がこう「『Pattern』 if 『Expression』」なのでそうなりますね

347デフォルトの名無しさん2021/12/22(水) 20:44:35.79ID:7pEHjDF/
sixtyfpsってどう?

348デフォルトの名無しさん2021/12/22(水) 22:58:00.27ID:mfli1g17
> しかし競プロでみんなproconioとかいう謎の専用ライブラリ使ってるの見た目悪すぎて笑える
いや、ほぼ公認のクレートなんだが・・・
謎の専用ライブラリとかいってる時点で、お察しか?

あと、見た目悪いってどういうことなんかね
includeしたら見た目悪すぎなわけ?

349デフォルトの名無しさん2021/12/22(水) 23:53:48.10ID:Wk3NOZd2
Rust bookの以下の記述について質問です

https://doc.rust-jp.rs/book-ja/ch19-05-advanced-functions-and-closures.html#クロージャを返却する
> 以下のコードは、クロージャを直接返そうとしていますが、コンパイルできません:
>
> fn returns_closure() -> Fn(i32) -> i32 {
> |x| x + 1
> }
> コンパイラには、クロージャを格納するのに必要なスペースがどれくらいかわからないのです。
> この問題の解決策は先ほど見かけました。
>
> fn returns_closure() -> Box<Fn(i32) -> i32> {
> Box::new(|x| x + 1)
> }

とBox化しなさいと書かれているのですが
以下のようにimplを付けるとBoxを使わなくてもコンパイルが通り動きました

fn make_closure_add1() -> impl Fn(i32) -> i32 {
|x| x + 1
}

このimpl付加は暗に自動的にBox化されているということなのでしょうか?

350デフォルトの名無しさん2021/12/23(木) 00:23:38.98ID:p+r9sE2/

351デフォルトの名無しさん2021/12/23(木) 07:21:11.33ID:esNMmzKz
>>348
そりゃあcratesio に上がったものは空っぽでもゴミでも全部公認だわなw

352デフォルトの名無しさん2021/12/23(木) 15:17:54.33ID:BEeWZFks
>>342
逆だ、コードは常に「正解」で動いていて「間違い」ない。

あんたの書いたバグもコンピューターにとっては一部の隙もなく正解であり、書かれたその通りに動き、無慈悲である。
同じ目的で、多数、あるいは二人の人が書いたコードで違いが出るのは「表現の違い」であり「間違い」と決めつける
のは人間の主観や嗜好でしかなく、仮にコードへ正誤を求めるなら明確に表現できていなればならず、矛盾が生じる

353デフォルトの名無しさん2021/12/23(木) 15:32:21.87ID:GoKXBRn5
コンパイルが通らないコードも正解なのかい?

354デフォルトの名無しさん2021/12/23(木) 15:39:30.16ID:9VjYa60R
えらいポエミーやな

355デフォルトの名無しさん2021/12/23(木) 18:55:13.24ID:TD851Muu
”動いていて”と言っているからコンパイルは通ってる前提だろう、”コードへ正誤を求める”といっているから
仮にコンパイルが通らないコードは明確にそれ(誤り・間違い)が表現できている
ポエミーなのはその通りだろう

356デフォルトの名無しさん2021/12/23(木) 21:22:53.78ID:NwYcCv97
>>349
Boxとはヒープを使うということです
Rustではコードで明示的に指定しない限り勝手にヒープが使われることはないです
(もちろんBox以外にもVecやStringなどヒープを使うものを使ってもそれは明示的に指定したことになります)

その Box<Fn(i32) -> i32> は今は Box<dyn Fn(i32) -> i32> と書く必要があります
では本題の impl Fn(i32) -> i32 と書いた場合はどうなるのでしょうか?
以下のように3種類のクロージャを作ってサイズや型を表示させてみると
fn main() {
 let direct_closure = |x: i32| x + 1;
 let impl_closure = make_impl_closure();
 let box_closure = make_box_closure();
 println!("{} {}", std::mem::size_of_val(&direct_closure), type_of(&direct_closure));
 println!("{} {}", std::mem::size_of_val(&impl_closure), type_of(&impl_closure));
 println!("{} {}", std::mem::size_of_val(&box_closure), type_of(&box_closure));
}
fn make_impl_closure() -> impl Fn(i32) -> i32 {
 |x| x + 1
}
fn make_box_closure() -> Box<dyn Fn(i32) -> i32> {
 Box::new(|x| x + 1)
}
fn type_of<T>(_: &T) -> &'static str {
 std::any::type_name::<T>()
}

実行結果は以下のように表示されます
0 tmp::main::{{closure}}
0 tmp::make_impl_closure::{{closure}}
16 alloc::boxed::Box<dyn core::ops::function::Fn<(i32,)>+Output = i32>
つまりimplでは直接クロージャ指定したのと全く同じです
(上記では定義した関数名だけが異なる)

357デフォルトの名無しさん2021/12/23(木) 21:33:09.04ID:soQwByyI
今日はポエマー多いなw

358デフォルトの名無しさん2021/12/23(木) 22:34:57.88ID:NwYcCv97
では常に impl を使えばよいのかというと
以下のような条件によって異なるクロージャを返す時
ここで Box を使わず impl Fn(i32) -> i32 にしようとすると
2つのクロージャの型が違うとコンパイラに怒られます

fn make_closure(curry: Option<i32>) -> Box<dyn Fn(i32) -> i32> {
 if let Some(curry) = curry {
  Box::new(move |x| x + curry)
 } else {
  Box::new(|x| x + 1)
 }
}

結局クロージャでない場合と同じ話で
同じトレイトでも型が異なるものが同居する時にBox化します
>>349のRust bookの例はBox化が不要なケースでBox化だから混乱しますね

359デフォルトの名無しさん2021/12/24(金) 11:53:17.86ID:8qqh3vKr
コンパイル通ってれば全て正解とかバカ丸出し。
厳密な定義でも使えない定義があるってことすら理解してなさそう。

360デフォルトの名無しさん2021/12/24(金) 12:05:46.49ID:0hdsBqvb
型安全だったらコンパイル通れば実行時エラーにならないという点で全て正解っていうのは別に間違ってないと思うけど?
これにケチつけるのは流石にどうかと

361デフォルトの名無しさん2021/12/24(金) 12:44:01.96ID:2tHLRFeD
バカ丸出しにお前バカだろとわざわさ言うのもバカなんじゃなかろうか

362デフォルトの名無しさん2021/12/24(金) 15:42:15.21ID:8qqh3vKr
>>360
実行時エラーにならないなんて最低限のところだっつーの。だからバカだっていうんだよ。

363デフォルトの名無しさん2021/12/24(金) 16:05:46.66ID:GD01KKAb
もしかしてrustはlinuxに取り込まれるわけねーだろって言い張っていた人?
予言外していたよね。お疲れ様です。

364デフォルトの名無しさん2021/12/24(金) 16:08:19.93ID:7q1GmIfa
バカをスルーできないバカっているよねー

>>364
お前の事な

365デフォルトの名無しさん2021/12/24(金) 16:10:39.10ID:GD01KKAb
なんか草

366デフォルトの名無しさん2021/12/24(金) 16:20:12.59ID:GD01KKAb
25 デフォルトの名無しさん sage 2021/04/27(火) 08:00:23.09 ID:/+bIFNU8
>>23
あのね。。書けばそうなるってものじゃなくてそれを実装しなきゃならんのよ。。
コンパイラにそういったコンテクストを判断させるのがめちゃくちゃ難しいっていってるでしょ?
なんでそんなに読み取れないの?

27 デフォルトの名無しさん sage 2021/04/27(火) 16:10:45.63 ID:/+bIFNU8
>>26
だからそのコードじゃpanic捉えきれねーからカーネルに入れるわけねーだろって
言ってんじゃん。。何読んでんだよ。

28 デフォルトの名無しさん sage 2021/04/27(火) 18:23:48.67 ID:n/AWrch2
まあ半年後どうなるかで誰が正しかったかは分かるわな

29 デフォルトの名無しさん sage 2021/04/27(火) 20:32:29.92 ID:/+bIFNU8
半年も経たなくてももうわかってるっつーの。。だからちゃんと英語の勉強しましょうね。

完全に同一人物だよね

367デフォルトの名無しさん2021/12/24(金) 16:26:02.78ID:GD01KKAb
https://lkml.org/lkml/2021/12/6/461

英語読めんならこれになんて書かれているのかわかるよね?

368デフォルトの名無しさん2021/12/24(金) 16:31:02.04ID:GD01KKAb
予想が完全に外れたID:8qqh3vKrを晒し上げ♪♪♪
ここまで簡単な予想を外すとかバカ過ぎて生きていけなさそうwww
馬鹿丸出しですねwwwwww

369デフォルトの名無しさん2021/12/24(金) 16:40:31.03ID:8qqh3vKr
素でバカなんだな。。もうコンパイル通ったんで俺の仕事終わりとか現場で言ってろよ。。話にもならん。

370デフォルトの名無しさん2021/12/24(金) 16:42:14.31ID:/xk3NPni
>>362
最低限の性質を満たしている⇔正解って言ってんじゃん。。何読んでんだよ。
なんでそんなに読み取れないの?
だからバカだっていうんだよ。
だからちゃんと日本語の勉強しましょうね。

371デフォルトの名無しさん2021/12/24(金) 16:45:16.93ID:/xk3NPni
>>369
なお予言を外したことについては一貫してノータッチwwwww
話をしたくないのは君だよねwwwwww

372デフォルトの名無しさん2021/12/24(金) 16:46:19.44ID:/xk3NPni
>>369
同一人物だってことはバレバレだっつーの。バカ丸出し。wwwwwwwwww

373デフォルトの名無しさん2021/12/24(金) 17:12:05.04ID:jmk0MHfo
どうでもええわRustの話しろ

374デフォルトの名無しさん2021/12/24(金) 17:38:56.03ID:8qNIErj3
厳密な定義でも使えない定義?Rustに特定条件下でCのような未定義になる動作あったっけ?

375デフォルトの名無しさん2021/12/24(金) 18:41:11.93ID:759ZBatD
スレの文脈はしらんけど、
Rustではunsafeを使ってなければコンパイラが、未定義動作が起きないということや、データ競合がないことを保証をしてくれるよ

376デフォルトの名無しさん2021/12/24(金) 19:10:24.57ID:/xk3NPni
>>369
予言外れましたよね?wwwwwwww

377デフォルトの名無しさん2021/12/25(土) 15:28:33.08ID:lsYj53Mi
Rustでフロントエンドしてる奴おる?

378デフォルトの名無しさん2021/12/26(日) 12:56:45.57ID:NwCcamJz
Rustの勉強を昨日から開始した。後は構造体とかかな。

379デフォルトの名無しさん2021/12/26(日) 17:26:13.09ID:rNqv+UWs
コード貼ったら糞だボケだゴミだと自称上級者に罵倒されるから注意しろ

380デフォルトの名無しさん2021/12/26(日) 19:27:36.42ID:IL2U4vJU
Rustはこう謳っている
>なぜRustか?
>パフォーマンス
>信頼性
>生産性
真っ向から反するコードを貼ってりゃゴミ・クソ言われて当然なんだよなぁ

381デフォルトの名無しさん2021/12/26(日) 19:29:23.79ID:Haex5ds9
すまんが、配列に入った数値の平均ってパッと出せないもんなの?
他言語でふにゃふにゃになった俺の頭でコードを書いたら、桁の溢れとか精度とか酷えことになりそう・・・・

382デフォルトの名無しさん2021/12/26(日) 20:24:04.94ID:s+fXV5dW
コードもゴミだったがそれ以上に考え方がゴミだったからな

383デフォルトの名無しさん2021/12/26(日) 20:42:21.32ID:M+F+5/6j

384デフォルトの名無しさん2021/12/26(日) 22:30:25.75ID:L9HJqboW
>>381
普通に平均を求めるだけではダメなのでしょうか?

fn main() {
assert_eq!(5.5, (1..=10).average());
assert_eq!(6.8, [2.3, 8.7, 9.4].average());
}

use num::ToPrimitive;
trait Average {
fn average(self) -> f64;
}
impl<I> Average for I
where I: IntoIterator, <I as IntoIterator>::Item: ToPrimitive,
{
fn average(self: I) -> f64 {
self.into_iter().fold((0.0, 1.0), |(ave, size), n| (ave + (n.to_f64().unwrap() - ave) / size, size + 1.0)).0
}
}

385デフォルトの名無しさん2021/12/27(月) 00:09:24.17ID:wxukv015
カハンの加算アルゴリズムというのがある

386デフォルトの名無しさん2021/12/27(月) 09:11:03.63ID:9DXmjbrK
汚コードキタ━!

387デフォルトの名無しさん2021/12/27(月) 10:50:10.93ID:BFpPIAiX
何でもトレイト化するアホ

388デフォルトの名無しさん2021/12/27(月) 12:29:15.17ID:PxL7gTAR
ゴミをゴミだといって何が悪い!

389デフォルトの名無しさん2021/12/27(月) 12:32:52.22ID:OyINMfYQ
ここの人たちってplaygroundとかなんで完全に動かせるコードで提示しないんだろ・・・?
アドバイス貰うにも回答するにも一生懸命スペース全角置換したり、まじ両方キモイw
trait Averagewwwww

390デフォルトの名無しさん2021/12/27(月) 13:09:28.61ID:PX/mZ8bI
こう言う時って普通の関数にしちゃいかんの?

391デフォルトの名無しさん2021/12/27(月) 14:19:38.18ID:Btn3kp2t
普通の関数にすべきかどうかはメソッドチェーンにしたいかどうかで判断すればよろしい

392デフォルトの名無しさん2021/12/27(月) 14:43:10.42ID:0vghZEjd
>>389
playgroundでは自己顕示欲が満たせないんだよw

まあplaygroundでは動かせないコードもあるけどな

393デフォルトの名無しさん2021/12/27(月) 15:03:42.29ID:6JVZDUUj
>>381
こういう子は、移動平均出したくなった時とかどうすんだろ…
愚直に毎回平均出す関数とか使っちゃうわけ?

394デフォルトの名無しさん2021/12/27(月) 21:04:27.03ID:K3JIQJJi
しょうがない、一応は専門家が書いているであろう他言語の実装を参考にしよう・・・・
https://source.dot.net/#System.Linq/System/Linq/Average.cs,2b4701af991d5425
俺様、信頼して使っていたメソッドの衝撃の事実を知る

395デフォルトの名無しさん2021/12/27(月) 21:09:19.15ID:h+0xE8z4
浮動小数点型ならそういう素直な実装で十分だよ

396デフォルトの名無しさん2021/12/27(月) 21:53:06.04ID:N7w3YVE+
>>384
それだと桁溢れは防止できているが誤差蓄積の対処ができていない
もう一つパラメタを増やしてこうしたほうがいい
fn average(self: I) -> f64 {
self.into_iter().fold((0.0, 1.0, 0.0), |(ave, size, fix), n| {
let diff = (n.to_f64().unwrap() - ave) / size - fix;
let new_ave = ave + diff;
(new_ave, size + 1.0, (new_ave - ave) - diff)
}).0
}

>>387
イテレータメソッド化するにはそのためのtrait宣言が必須
もしわからないならitertoolsなどのイテレータ拡張ライブラリを見よう

>>389
標準ライブラリのsum()がtrait Sumを使っているからtrait Averageでもまあいいとは思う
ただし今回はイテレータメソッド拡張のみに用いているようだからtrait IteratorExtなどの命名がわかりやすいとは思う

397デフォルトの名無しさん2021/12/27(月) 21:56:50.25ID:20E7BwbM
IteratorExt大草原、まじに入院してほしいw

398デフォルトの名無しさん2021/12/27(月) 22:01:57.73ID:6/3kWl6D
イテレータメソッドにする必要ある?

399デフォルトの名無しさん2021/12/27(月) 22:15:24.91ID:N7w3YVE+
>>398
標準ライブラリにおいてsum()やproduct()
それを一般化したfold()やreduce()
さらにmax()やmin()など当然イテレータメソッドになっている
むしろ今回のaverage()だけをイテレータメソッドにしない理由が見当たらない

400デフォルトの名無しさん2021/12/27(月) 22:20:18.56ID:6/3kWl6D
>>399
じゃあなんで標準ライブラリにないの?

401デフォルトの名無しさん2021/12/27(月) 22:25:16.01ID:h+0xE8z4
カハンの加算使ったのか

402デフォルトの名無しさん2021/12/27(月) 22:31:56.63ID:/o/Y1bP3
>>400
入力型と出力型で大量の組み合わせ(例:i32→f32)が用途に応じて要求されるのと
単純に合計をサイズで割った平均でよい用途もあれば
件数が多いと合計がオーバーフローするからその対策が欲しい用途もあれば
桁が大きく異なるデータ列の場合に浮動小数点の誤差改善が欲しい用途など多岐にわたる
だから平均を標準ライブラリで何か一つ用意は無理

403デフォルトの名無しさん2021/12/27(月) 22:51:58.74ID:Btn3kp2t
単にこれまで標準ライブラリに入れようとした人がいなかったか
そういう人はいたが必要性を説得できなかっただけでしょう
sumやproductに比べるとユースケース限られるしね

404デフォルトの名無しさん2021/12/27(月) 23:21:10.48ID:iNGO9QKv
"ave"のせいで頭に入ってこない

405デフォルトの名無しさん2021/12/28(火) 00:10:56.21ID:THzUMFur
「件数が多いと合計がオーバーフローするからその対策が欲しい用途」そんな考えがオカシイ
sumですらオーバーフローに言及しているだけで対策が欲しいから、だからstdじゃないという理由では無い
https://doc.rust-lang.org/std/iter/trait.Iterator.html#panics-3
When calling sum() and a primitive integer type is being returned, this method will panic if the computation overflows and debug assertions are enabled.

必要性を説得出来ないだけというのが正しい。浮動小数の加減算による誤差蓄積だって、浮動小数を扱うなら当然起こることだが
誤差改善が欲しい用途があるからstdじゃないとか嘘ばっかり言わないで?おまえさ、迷惑だからRust辞めてくれよ?
最小限、分かったふりで糞まき散らすな?

406デフォルトの名無しさん2021/12/28(火) 00:45:10.69ID:vzPVHyZI
>>405
それは君が無知
平均算出にはsumを求めずとも差分を逐次的に適用するアルゴリズムがあるoverflowを回避する対策で一般的に使われている
例えば>>383のstatsもその方法で平均を算出している
sumの例を出すのは見当違い

407デフォルトの名無しさん2021/12/28(火) 00:52:41.14ID:We8KhoPF
>>406
アルゴリズムの話じゃなくてstdに入ってない理由の説明がおかしいという指摘だと思うよ
言葉汚いし何言ってるかわかりづらいけど

408デフォルトの名無しさん2021/12/28(火) 01:20:29.34ID:vzPVHyZI
>>407
stdに入ってない理由?
一長一短ある複数のアルゴリズムがあるから外部でいいだろう

409デフォルトの名無しさん2021/12/28(火) 01:57:17.15ID:We8KhoPF
>>408
その理屈だとsortも該当するが
そもそも前提としてaverageをstd

410デフォルトの名無しさん2021/12/28(火) 02:00:22.76ID:We8KhoPF
>>409
途中で書き込んでしまった

そもそもaverageか類似の関数をstdに取り込む議論が過去にあったならそれをポイントしてほしい

411デフォルトの名無しさん2021/12/28(火) 02:37:31.31ID:vzPVHyZI
多数あり外部で十分派なのでそこは興味ない
sortは2種類しかなく2種類とも標準ライブラリでサポートしている

412デフォルトの名無しさん2021/12/28(火) 09:30:51.41ID:y5zg5Cpt
>>411
じゃ一番メジャーな外部ライブラリを教えてよ

413デフォルトの名無しさん2021/12/28(火) 10:24:44.25ID:ZpntEDp9
外部で十分と言えば、cratesは先着順で名前取れるからこの先優良ライブラリ程クソみたいな名前になっていくよね

414デフォルトの名無しさん2021/12/28(火) 10:41:12.74ID:zga8SsrA
>>413
マジでこれ
いい名前取るだけ取って何年も放置とか多すぎ
なんかいい方法無いかねぇ…

415デフォルトの名無しさん2021/12/28(火) 11:15:50.74ID:ZpntEDp9
ライブラリの永続性を保つのに名前でマッチさせるのやめてUUIDかハッシュか何かでマッチさせれば良かったのにみたいな気持ちはある

416デフォルトの名無しさん2021/12/28(火) 11:32:06.72ID:HJMjm+0C
>>414
横から失礼。
個人的にはそもそもcrate.io に頼るのがあまり好きでないなと。
Rust に限らない話だけど、こういった中央集権的なリポジトリを用意すること自体が名前争奪戦の元になるのではないかなと。
それぞれのWEBサイトで勝手に配布すればいいのにってね。
バージョン管理方法の方法論なんかも関わるから簡単な事ではないんだろうけど。

417デフォルトの名無しさん2021/12/28(火) 11:35:30.26ID:QBGkL4gv
現状でもGitHubから直接落としてくることも出来るけど、GotHubのリポジトリは消せてしまうからな

418デフォルトの名無しさん2021/12/28(火) 13:40:51.12ID:XD/wAJcN
cargo updateでマイナーバージョンアップやらせるのも規約決めたり工夫ご必要だし
専用のリポジトリ用意する方がわかりやすくはあるような
crates.io以外にも複数のリポジトリを混在して使えるようにできれば良いのかな

419デフォルトの名無しさん2021/12/28(火) 14:10:43.98ID:Qs/YVt0a
cargoはどこからでも落とせる
crates.ioなみに安全性、信頼性、永続性が確保できるんなら好きにすればいい

420デフォルトの名無しさん2021/12/28(火) 14:45:21.34ID:ZpntEDp9
永続性を謳うサービスで名前で管理したらそりゃあいい名前の取り合いになるよなあ

421デフォルトの名無しさん2021/12/28(火) 14:48:37.23ID:XD/wAJcN
>>419
ほんとだ、packageごとにregistry指定できるんだね
https://doc.rust-lang.org/cargo/reference/registries.html

422デフォルトの名無しさん2021/12/28(火) 15:16:22.59ID:c9bIiubz
GoみたいにGithubがデファクトスタンダードなレジストリになっても一覧性の面で不便だし、crates.ioでいいと思うけどなあ

423デフォルトの名無しさん2021/12/28(火) 21:31:42.32ID:VUBOa1a1
セキュリティ監査付きのcrates.ioクローンが欲しい

424デフォルトの名無しさん2021/12/28(火) 21:33:45.43ID:m5VlhgmG
average()が気になってcratesだかcargoだか話逸らしに聞こえる

425デフォルトの名無しさん2021/12/28(火) 22:07:01.63ID:a7HoB6QX
ぼぼぼ、ぼくちんのために誰か優秀なaverage()をおながいします

426デフォルトの名無しさん2021/12/28(火) 22:22:38.58ID:ndrZKvgW
>>423
cargo auditでは足りない?

427デフォルトの名無しさん2022/01/01(土) 09:34:17.63ID:f7mn356m
>>411
「多数あり外部で十分派」なのに>>412には答えられないの??

428デフォルトの名無しさん2022/01/01(土) 19:34:25.31ID:u2SyaqDt
Why is my Rust build so slow?

429デフォルトの名無しさん2022/01/01(土) 20:01:31.38ID:YfLqYQwV
Because your PC is poor spec.

430デフォルトの名無しさん2022/01/01(土) 23:44:42.88ID:193tzZ58
https://fasterthanli.me/articles/why-is-my-rust-build-so-slow
この人の場合クソデカ型のせいでコンパイルが遅かったという話

431デフォルトの名無しさん2022/01/02(日) 10:42:43.84ID:adsjh4PJ
warpがクソみたいに重いって書いてるな

432デフォルトの名無しさん2022/01/02(日) 11:21:24.79ID:ulXuEZX0
sccacheとか入れてみるか

433デフォルトの名無しさん2022/01/02(日) 13:52:17.06ID:o9R7ffl7
当日お急ぎ便でSSDを買った

434デフォルトの名無しさん2022/01/02(日) 14:41:20.14ID:N3sGBcjr
>>432
bin crateのビルドに時間かかるなら sccache は効果薄いのでは

435デフォルトの名無しさん2022/01/02(日) 14:53:21.62ID:3FXnOBLq
高度IT人材、富士通は最大年収3500万円へ

「富士通年収3500万!」日本のIT企業の年収も、高額化してきました

AI人材の獲得に超本気 NECが新人事制度を9人に適用、富士通は最大年収3500万円へ

【年収3500万円も】富士通、「ジョブ型」人事制度を導入 幹部社員から 高度IT人材

来年度から副業解禁 人材多様化へ―大同生命次期社長

第一生命HD、副業解禁 約1万5000人対象

第一生命HD、副業解禁 1万5000人対象―大手生保初

IHI、国内8000人の副業解禁 重厚長大企業も転機

IHI、社外兼業を解禁 社内副業もルール化

436デフォルトの名無しさん2022/01/02(日) 21:56:13.39ID:Uu3cvt4h
効率を求め過ぎてモノリシックになりすぎると様々なコストが上昇してしまう
そこで分割
さらに内部もcrate分割で並行コンパイル

437デフォルトの名無しさん2022/01/04(火) 02:27:09.98ID:L+p8nbVX
Rustでノードが追加されたり消されたりする双方向グラフ扱いたくなったらどうするんだろ
Arenaじゃ追加削除してるうちにゴミがメモリ圧迫していくし

438デフォルトの名無しさん2022/01/04(火) 09:43:25.00ID:aGnbM+4r
>>437
Cursor使う

Arenaの場合はfree list用意して削除済み要素を再利用すればよい
Arenaが埋まったらreallocするのではなく同じサイズの新たなArenaを獲得していくようにすれば
不要になったArenaから解放できるからmalloc使う場合と同等のメモリ使用量に抑えられるかと
これでも不足するなら copy GC 的に compaction するしかなさそう

439デフォルトの名無しさん2022/01/04(火) 18:15:54.62ID:L+p8nbVX
>>438
なるほど…… 結構ガッツリ実装しなきゃいけなそうね。ありがとう。最後はGCを実装することになりそうなので、それならいい感じのGCを残しておいてくれたら良かったのにって気になるな

440デフォルトの名無しさん2022/01/04(火) 18:22:33.23ID:L+p8nbVX
Cursorってなんでしょう?

441デフォルトの名無しさん2022/01/04(火) 19:44:07.16ID:aGnbM+4r

442デフォルトの名無しさん2022/01/04(火) 20:59:48.62ID:/2oFrrnl
>>439
GCを必要とする用途は非常にレア
だから標準ライブラリには不要だが外部ライブラリに色々あるので大丈夫

443デフォルトの名無しさん2022/01/04(火) 22:15:51.15ID:aGnbM+4r
>>442
GCのライブラリ使ったことある?実用的だった?

444デフォルトの名無しさん2022/01/04(火) 22:53:03.36ID:NZNEJALT
特殊な案件でしかGCを使うことはないため
その場合は汎用GCライブラリ利用よりも
データ構造とアロケーションとGCを密に設計する方がベターかも

445デフォルトの名無しさん2022/01/05(水) 00:28:17.64ID:GzN74lxE
ちゃんとしたスマートポインタを自作する時点で結構大変だから用途特化した方が確かによさそう

446デフォルトの名無しさん2022/01/05(水) 01:03:11.75ID:o/mlVe5X
グラフみたいなデータ構造を実装するだけでも、GCが必要になったりするもんなん?

447デフォルトの名無しさん2022/01/05(水) 01:37:16.98ID:hbslRCuW
>>441
ありがとうございます!

448デフォルトの名無しさん2022/01/05(水) 01:46:20.36ID:yOKwmyBj
グラフ構造表現するだけならArenaや、少し安全にするならGenerationalArenaで事足りるかと
copy GC的なものが必要になるのは大量にノードを作成してほとんど削除、一部残存みたいな状況でfreeできないArenaが残ってしまうケース

449デフォルトの名無しさん2022/01/05(水) 04:00:13.07ID:6kre97ZR
ちゃんとしたGCはないのに、参照カウントだけは標準ライブラリに入っていて循環参照には気をつけましょうねーって運用でカバーなのはなんか中途半端なものを感じる
そもそも参照カウントなんてGCとしてはかなりイケてない部類なのになんで参照カウントなんだ気持ちもある

450デフォルトの名無しさん2022/01/05(水) 04:09:37.27ID:VoX97L81
単純にRcやArcはGCを目的としたものではないから

451デフォルトの名無しさん2022/01/05(水) 06:50:20.96ID:wTheSKj8
分かってる風で語るのはカッコ悪いね

452デフォルトの名無しさん2022/01/05(水) 07:42:18.23ID:jCayWhDI
単なるスマートポインタをGCと言っちゃうあたり・・・
あれは単にRAIIでヒープを処理してるだけのことであって
わざわざGCと呼ぶような大したもんではない

453デフォルトの名無しさん2022/01/05(水) 07:48:16.03ID:yhx54h3v
9分で轟沈したのに2時間後に死体蹴りせんでも。

LLVMにレジスタとスタック使わないよう教える術がないし
rustは意地でもスタックに置きたがるしplacement系が削除されたから保守的になるよね。
実際、保守的gcってどれくらい回収できんの?

454デフォルトの名無しさん2022/01/05(水) 07:52:39.60ID:/PNLes9I
>>449
即時解放がやりやすい&実装が簡単だから、だろ。

そういう説明をしないで>>452とか言うやつはRust普及の足を引っ張っているだけだから、書き込みしないほうがいいと思う。

455デフォルトの名無しさん2022/01/05(水) 08:39:25.19ID:yhx54h3v
>>454
>>450の言う通りrustのreference counting gcは
メモリ管理のためではなく共有された参照を数えるためのもので
シングルスレッド用のRcがあるのはrustがaffine typeだから
共有された可変を認めないからで、ついでに>>452の言うことも半分あってるよ。
rustは自動参照カウントにRAII併用するけどgcのない言語しか経験がない人が
gcをスマートポインタと混同するのもよくある事。

あと、rustの参照カウンタは弱参照があるから循環参照が切れる代わりに
単純な参照カウンタのオーバーヘッドが少ない・開放されるタイミングが
予測可能というメリットはないからrustが参照カウンタを用意する
メリットは>>450が指摘したものしか無いよ。

456デフォルトの名無しさん2022/01/05(水) 09:30:04.08ID:HAtvMNOo
学問的には参照カウントはGCの一方式として分類されるのが普通だよ
まあなんの前置きもなくGCといったらトレーシングGCがイメージされるというのもその通りだが
RcがGCだと言っても間違ってるということはない

RustのstdにトレーシングGCがないのは、単に標準ライブラリを大きくしない方針に従ってるだけじゃない?
本格的なGCが必要なケースは限られるし、外部クレートで十分と思うが

457デフォルトの名無しさん2022/01/05(水) 09:44:11.20ID:l0gfYUX+
いつものやつホント気持ち悪いな

458デフォルトの名無しさん2022/01/05(水) 12:11:20.98ID:g7d2BHp/
>>457
コテハンつけるかID変えないならまだいいんだけどな

459デフォルトの名無しさん2022/01/06(木) 01:29:23.74ID:Izanmpcc
気持ち悪さは長文から来る。reference counting gcとかわざわざ参照カウントを英文で書いてカッコつける所も
減点項目。個人の主観的には文中に>>を挟む特徴が読み手の事を一切考えないオナニーに見える

460デフォルトの名無しさん2022/01/06(木) 08:00:17.28ID:AA9pZn/O
それあなたの感想ですよね

461デフォルトの名無しさん2022/01/06(木) 08:47:42.41ID:zkS6fEay
文中に >> 挟むのだめなのか
どのレスのこと指してるのか明確になって良いと思うが

462デフォルトの名無しさん2022/01/06(木) 09:03:44.55ID:8b5imbdG
>>レス番
↑これで引用先に飛べるリンクが張られるの知らなさそう
5chにPCからアクセスしたり
専用ブラウザからアクセスしたときそうなってるのよ

463デフォルトの名無しさん2022/01/06(木) 10:12:38.67ID:soGE7KAW
Rustのメモリ安全性ってどうやって保証してんの?
テスト?

464デフォルトの名無しさん2022/01/06(木) 11:33:54.14ID:Djcmy5st
>>462
君はHTML知らなそうw

465デフォルトの名無しさん2022/01/06(木) 16:21:52.81ID:a887VGZI
ダメというわけじゃないが、同じ人が言ってるわけじゃないのに文中に一つにまとめて自分の考えだけを
長々と話している時点で意味わからん、リンクの話じゃない。気持ち悪さがどこからくるかという話。
感想といえばその通りで、個人的な主観と言ってるが多くの人はそう感じるのはこうではないか?という話

466デフォルトの名無しさん2022/01/06(木) 17:27:19.44ID:Gs63EiHG
長いから3文字にまとめて😪

467デフォルトの名無しさん2022/01/06(木) 17:28:58.84ID:fX6pq/OF
>>465
Rustスレで学級会始めるおまえも気持ち悪いよ

468デフォルトの名無しさん2022/01/06(木) 17:49:08.32ID:AA9pZn/O
>>がリンクにならない環境を知らんのだが

469デフォルトの名無しさん2022/01/06(木) 18:13:44.84ID:jbChckmf
>>465
よくわかる
いつも中身ないので即NG
だがやつは自演魔なんでマジタチ悪い

470デフォルトの名無しさん2022/01/06(木) 21:11:27.35ID:Q5dnJVm5
>>469がいつものキチガイの典型例
文句をつける意味不明な書き込みをしてその後に自演で同意のレスを付けてくる
スレを荒らすことが目的

471デフォルトの名無しさん2022/01/06(木) 22:28:23.35ID:s+xoikwS
お前らが誰と戦ってるのか
正直理解できない

472デフォルトの名無しさん2022/01/06(木) 23:39:45.17ID:ZA0J9QW6
このスレ常駐の荒らしは以下の特徴があるから無視すればよい
「気持ち悪」「ゲロ」「汚」などの言葉を好む
別案・別情報・別解釈などを具体的に出せず文句を付けるだけ
そのような無意味な書き込みになぜか賛同レス

473デフォルトの名無しさん2022/01/06(木) 23:48:00.39ID:NzY/+9uF
などと>>455氏が言っており

474デフォルトの名無しさん2022/01/07(金) 00:34:18.06ID:QTrF6/lG

475デフォルトの名無しさん2022/01/07(金) 00:34:18.20ID:cXPu1ueH
>>463
コンパイル時にチェックされるものと実行時にチェックされるものがあるよ
多くの場合は前者で済むけど、可変参照を複数箇所で共有したい場合は後者が必要になる

476デフォルトの名無しさん2022/01/07(金) 01:59:05.78ID:QJvziKfk
キモいと思うレスは黙ってNGしといてこれやるといいよ
https://dtolnay.github.io/rust-quiz/

Rustの文法はもうバッチリと思ってる人向け
重箱の隅をつつく問題なんだけどすごく勉強になる

477デフォルトの名無しさん2022/01/07(金) 03:03:06.42ID:7ncHJZDo
クソむずい

478デフォルトの名無しさん2022/01/07(金) 08:11:58.75ID:AAqP4BQM
c++の悪いとこばっか真似してどうすんの。。

479デフォルトの名無しさん2022/01/07(金) 08:58:17.17ID:3q+e3WNv
>>475
コンパイル時のチェックって結局人手で書いたコードによるチェックなんでしょ?
ということは担保は単体テストってこと?

480デフォルトの名無しさん2022/01/07(金) 09:16:18.88ID:3w3matv0
>>479
実行時じゃなくて?

481デフォルトの名無しさん2022/01/07(金) 09:25:48.12ID:9KLybwvT
そもそもだかマシン語でみりゃ
メモリに型もなんもないよw
単なるバイトだらけ
コンパイルの段階で変なコードか
けないようにしてるだけ
でもこれだとぬるぽ!が回避できないので
仕方なく仕組み入れたのがRustでしょ

482デフォルトの名無しさん2022/01/07(金) 10:01:43.31ID:FjJ2oZu9
Rust書くときは常にIDEに直してもらいながら書いてるから>>476みたいなの全然解けないわw

483デフォルトの名無しさん2022/01/07(金) 10:06:26.42ID:27W+wb2V
>>476
確かにこれは勉強になる
知らなかったことばっかり

484デフォルトの名無しさん2022/01/07(金) 10:10:35.06ID:FVraLxVf
Rustのメモリ安全って、null安全のことだったの?しょぼ

485デフォルトの名無しさん2022/01/07(金) 10:57:05.72ID:9qeGIYdY
>>479
コンパイラのコードのこと?
安全性の保証に形式的証明を与えようという取り組みはあるけどコンパイラの実装が正しいかはコンパイラのテスト頼りだね
https://plv.mpi-sws.org/rustbelt/popl18/

486デフォルトの名無しさん2022/01/07(金) 11:28:53.58ID:9KLybwvT
「Rustは安全でも難しい」といわれる理由――メモリ安全を実現する「所有権」の仕組み
https://atmarkit.itmedia.co.jp/ait/spv/2111/25/news008.html

487デフォルトの名無しさん2022/01/07(金) 12:00:56.69ID:24FxYl/s
>>486
初心者向けにわかりやすく解説しようという試みは評価するが
間違いが多すぎて萎える
ここで初心者の質問に回答してる初心者と同じ

488デフォルトの名無しさん2022/01/07(金) 12:22:15.55ID:9qeGIYdY
>>487
例えばどこが間違ってるの?

489デフォルトの名無しさん2022/01/07(金) 18:09:24.83ID:KzGvgOV1
>>488
整数型や浮動小数点型といったスカラー型の変数は、変数間の代入において所有権は基本的に複製されます。これを「所有権の複製(コピー)」といいます。変数間の代入などにおいて所有権は複製されるので、値の所有者は常に1個でなければならないというルールは守られます。

490デフォルトの名無しさん2022/01/07(金) 19:34:39.40ID:9qeGIYdY
>>489
正しいこと言ってるように見えるけど
どう間違ってるの?

491デフォルトの名無しさん2022/01/07(金) 19:39:44.12ID:pFd15XiZ
所有者が無能だったら終わりです

492デフォルトの名無しさん2022/01/08(土) 00:17:04.62ID:GxMqZbIC
所有権が複製されるって表現はなんかRcを想像してしまうな

493デフォルトの名無しさん2022/01/08(土) 00:19:22.76ID:tLJ6VgIA
整数型とかの単純のヤツはCopyだかCloneだかをderiveしててデフォのmove semantics機能してなかった気がするな
最近書いてねぇから忘れてんなこれ(´・ω・`)

494デフォルトの名無しさん2022/01/08(土) 06:57:19.85ID:5x1u92SJ
数値型が特別扱いされているわけではない
Copy traitを実装すればcopyされる
Copy traitを実装しなければmoveされる

495デフォルトの名無しさん2022/01/08(土) 23:30:01.75ID:lz8RPHEi
Copyで複製されるのは所有権じゃなくて値だよね
代入先の変数が複製された新しい値の所有権を持つことになるけど、所有権が複製されるんじゃあない

496デフォルトの名無しさん2022/01/09(日) 16:14:36.11ID:uxfV5OFq
copyだけでなくmoveされるのも対象は値
所有権ではない

値をmoveした結果
値に紐付く所有権がくっついてくる

497デフォルトの名無しさん2022/01/09(日) 16:51:12.42ID:TifKF/RV
値と同時に所有権 "も" copy/moveされると捉えることもできるのでは

498デフォルトの名無しさん2022/01/09(日) 18:01:55.54ID:yd7evZmg
個人的に間違った捉え方をするのは自由だが
それを初心者に広めるのはやめていただきたい

499デフォルトの名無しさん2022/01/09(日) 18:56:17.00ID:KYx55eM0
あんたらのお仲間他スレで暴れてばかりだよ、引き取りに来い

500デフォルトの名無しさん2022/01/09(日) 19:06:20.22ID:EvEIewTi

501デフォルトの名無しさん2022/01/09(日) 19:18:00.80ID:n32zl2Pe
所有権が複製できちゃったら「一個の値に一個の所有者」ってルールが守れないやん(´・ω・`)

502デフォルトの名無しさん2022/01/09(日) 20:01:19.31ID:wa3WbZ82
所有権を持っていると年2回の配当金がもらえます

503デフォルトの名無しさん2022/01/09(日) 20:12:54.12ID:ASvenOj7
しょーゆー拳!

504デフォルトの名無しさん2022/01/09(日) 20:17:43.06ID:QVmVQA75
>>492
> 所有権が複製されるって表現はなんかRcを想像してしまうな

https://doc.rust-lang.org/std/rc/index.html
> The type Rc<T> provides shared ownership of a value of type T

shared ownershipという表現でうまく説明できててrustっていいなと思う

505デフォルトの名無しさん2022/01/09(日) 20:20:09.14ID:Yd6TUYc2
というかCあたりの関数の引数も
コピーじゃなかった?
中身を渡した先でもいじらせる場合とかは
ポインター渡しとかなんかやってた記憶

506デフォルトの名無しさん2022/01/09(日) 21:35:14.41ID:f6gH817b
大半の言語はデフォルトで値渡しだよ

507デフォルトの名無しさん2022/01/09(日) 21:41:43.59ID:QVmVQA75
Cでポインタ型の値を渡してるだけのことを
参照渡しと言っちゃう害悪がネットにチラホラ残ってて悲しい
ポインタ渡しとかいうすっとんきょうな用語も必要性を感じない
Javaで単に参照型変数の値を渡してるだけのことを
参照渡しと言っちゃうのも割りとあって悲しい

508デフォルトの名無しさん2022/01/09(日) 21:57:11.88ID:DflwLcIO
>>501
そう捉えるのが普通だよな

509デフォルトの名無しさん2022/01/09(日) 22:12:54.92ID:tE6q+RNQ
>>501
値が複製された場合なら問題ないんでないの?

510デフォルトの名無しさん2022/01/09(日) 22:21:03.82ID:uOSYnK8a
Rustは非常にシンプルで
Copy traitが実装されていない型は値と所有権がmoveされる
Cooy traitが実装されている型は値がcopyされてその値に新たな所有権が生じる

もちろんそれを所有権と値が複製されたとみてもよい
ちなみにRcは所有権の複製ではなく所有権の共有

511デフォルトの名無しさん2022/01/09(日) 22:28:10.17ID:ec1b4GYb
「所有権とは、文字通り変数が値を所有できる権利のことです。」
ふむふむ

「スカラー型の変数は、変数間の代入において所有権は基本的に複製されます。これを「所有権の複製(コピー)」といいます。」
ふむふむ・・・

「変数間の代入などにおいて所有権は複製されるので、値の所有者は常に1個でなければならないというルールは守られます。」
・・・は?
元の値を所有できる権利を複製したんじゃなかったの?

512デフォルトの名無しさん2022/01/09(日) 22:37:27.87ID:uOSYnK8a
>>511
所有権と値は必ずセットで複製される
当たり前だが片方だけが複製されることはありえない
必ず1対1の関係になる
ちなみにRcの場合は所有権は複製されずに所有権の共有となる

513デフォルトの名無しさん2022/01/09(日) 22:41:22.81ID:zMIZ+Krn
>>511
>変数が値を所有できる権利のこと
"所有できる権利"という捉え方が良くないね

514デフォルトの名無しさん2022/01/09(日) 23:30:44.08ID:enp/nJFU
>>489
所有権だけが複製されるわけじゃないし、たしかに不自然だな

515デフォルトの名無しさん2022/01/10(月) 00:03:57.12ID:x5u3TTyT
>>509
複製された(結果的に値は同じだけどメモリ上の位置は異なる)新たな値に対する新たな所有権を「所有権が複製される」って表現するのはおかしいべ?


>>510
そこよく勘違いされてるけど値自体はCopyトレイトと関係なく常に複製されてるよ(最適化で除かれるとかは別として)

https://doc.rust-lang.org/std/marker/trait.Copy.htmlに全部書いてあるけど
Copyな型は「プリミティブ型みたいに単純にメモリの内容を複製するだけでオッケー=copy」
非Copyな型は「ポインタとか含まれてたりして単純にメモリの内容を複製するだけだとNGな可能性があるから古い方は使えなくするよ=move」
ってだけ

516デフォルトの名無しさん2022/01/10(月) 11:29:11.88ID:0oVbzL+8
>>515
ルールを守れるか守れないかという話。
表現としておかしいかどうかは結論なんて出せないんじゃね?公式ドキュメントででも謳ってない限り。

517デフォルトの名無しさん2022/01/10(月) 20:14:15.89ID:tVKp4zEB
著者のバックグラウンド見る限りC/C++の経験があるオレならRustも分かっちゃうよ?みたいな連載だから表現が慣れてなくても気にしない
監修もRustの人っぽくなさそうだし…多分、関数型の語彙が無いんじゃないかね

518デフォルトの名無しさん2022/01/10(月) 20:29:16.07ID:DRRBVfd3
うんこ言語を好意的に連載してる記事をこき下ろす性格の悪いRusterが集まる駄スレ

519デフォルトの名無しさん2022/01/11(火) 03:16:23.27ID:DWOD4ihn
>>515
> そこよく勘違いされてるけど値自体はCopyトレイトと関係なく常に複製されてるよ(最適化で除かれるとかは別として)
>
> https://doc.rust-lang.org/std/marker/trait.Copy.htmlに全部書いてあるけど

へー、なるほど、いろいろ納得したわ

520デフォルトの名無しさん2022/01/11(火) 11:05:54.30ID:U35zy9ok
>>518
だよなぁ。
誰か筆者に指摘した?

あと、「所有権の複製(コピー)」はRustだと実際は何て言ってるの?

521デフォルトの名無しさん2022/01/11(火) 12:25:22.53ID:yQgVkZD8
「所有権の複製」でググってもほぼ誰も使って無い用語で草

522デフォルトの名無しさん2022/01/11(火) 12:27:41.85ID:zYBpR5AJ
所有権だけをすることなんてないだろうし、そんな言葉なくね
そもそも意味わからん

処理系を実装してる人にとっては考えることかもしれんが

523デフォルトの名無しさん2022/01/11(火) 12:28:11.69ID:zYBpR5AJ
所有権だけを複製すること、の間違い

524デフォルトの名無しさん2022/01/11(火) 21:25:05.09ID:On+Ztxm9
まあ無駄にややこしいだけの説明だわな。
これで間違ってない!とか意地張るような輩は俺だったら落とすわ。

525デフォルトの名無しさん2022/01/11(火) 21:31:59.06ID:xKqG3MQU
どっちに解釈しても問題ない話の一方に固執する方がお断りだな。

526デフォルトの名無しさん2022/01/11(火) 22:00:42.75ID:7fHp9GHd
所有権の複製の意味が分からん
不用意に独自用語使うのを野放しにしちゃいけない
専門用語とその定義がなぜあるのかを考えて欲しい

527デフォルトの名無しさん2022/01/11(火) 22:43:07.52ID:2061HgWk
>>519
実際に生ポインタ(アドレス)を見る形で実験したところ
「関数に値渡し(≠参照渡し)する」時は
「Copy trait実装の有無」に関係なく
「必ず値は複製されている(=別アドレスになる)」という
よく考えれば当たり前の挙動となった

つまり話をまとめると
・Copy trait実装の有無と関係なく「値は必ず複製される」
・Copy trait実装がある時は「所有権も複製される」
・Copy trait実装がない時は「所有権は移動する」
これ以外に表現しようがないことがわかった

528デフォルトの名無しさん2022/01/11(火) 23:09:26.60ID:On+Ztxm9
メモリ上の動きと言語上のルールの違いもまともに理解してなさそうな連中だな。

529デフォルトの名無しさん2022/01/11(火) 23:49:06.82ID:t1MM9BO+
mutの時に書き換えると元の値と別の値に出来るのだから新たな所有権が生じているのは事実
あとは、所有権の複製、という表現の問題
間違ってはいないが理解しにくいならば別の良い表現で置き換えればよいが何がいいだろう?

530デフォルトの名無しさん2022/01/12(水) 00:52:45.70ID:1lKX/EK6
値が複製されるのに伴って新たな所有権が生成される

531デフォルトの名無しさん2022/01/12(水) 08:45:55.15ID:zdKxvEH9
ムーブの場合は元の所有権が破棄されて新たな所有権が生成される

532デフォルトの名無しさん2022/01/12(水) 10:38:50.42ID:uD0wFQGQ
値を複製したらメモリの領域が別なのに「所有権の複製」は何を複製すると思ってんだろ

533デフォルトの名無しさん2022/01/12(水) 18:27:19.23ID:5pTy1wN9
>>532
さっぱりわからんよな

>>529
> 間違ってはいないが理解しにくいならば

何言ってんのコイツ?

534デフォルトの名無しさん2022/01/12(水) 21:24:46.00ID:zdKxvEH9
全く同じものを新しく生成するのと複製は外から見て区別しようがないんだから

535デフォルトの名無しさん2022/01/12(水) 22:30:30.00ID:y9ayzVSo
所有権はコンパイル時のはなし
メモリの動きは実行時のははし

536デフォルトの名無しさん2022/01/12(水) 23:21:45.30ID:mVKgaRWA
セマンティクスの話をしろ

537デフォルトの名無しさん2022/01/12(水) 23:51:37.77ID:DMKGOQqO
現実世界の所有権が複製可能な権利だったのなら
複製されると勘違いする人がいても不思議はないが・・・

538デフォルトの名無しさん2022/01/13(木) 08:49:48.70ID:+PFReeTS
質量保存則に縛られる現実世界の複製との対比には限界があるわな。

539デフォルトの名無しさん2022/01/13(木) 10:12:58.78ID:8S0jzhzB
権利のような無形物は質量保存則には縛られない

Borrow Checkerが課すルールをわかりやすく説明するためのメタファーとして
現実世界の所有権という概念を借りてきてるのに
そのメタファーを分かりにくくするエクストリームなルールを勝手に追加して広めるのはやめよう

540デフォルトの名無しさん2022/01/13(木) 10:57:22.74ID:VN3LqOp5
https://users.rust-lang.org/t/what-is-the-formal-definition-of-ownership/41984
なんか同じようなやり取りして同じように最終的にグダグダなまま閉じてて草

541デフォルトの名無しさん2022/01/13(木) 11:03:58.63ID:4F526BmN
というかRustの実装のところ見ればいいんじゃね?
仕組みのコードはあるだろうし

542デフォルトの名無しさん2022/01/13(木) 11:11:48.72ID:0M0jmEeK
見るまでもないだろw

543デフォルトの名無しさん2022/01/13(木) 12:20:30.48ID:k/BdCeDW
https://doc.rust-lang.org/rust-by-example/scope/move.html
ここでは所有権が移動される(the ownership of the resources is transferred)とあるから
ここからの類推で所有権の複製という言葉が出てきたのかな

544デフォルトの名無しさん2022/01/13(木) 12:30:05.91ID:H8cLP4dt
Ownershipを所有権と訳したから
「所有権とは、文字通り変数が値を所有できる権利のことです」
という間違った解釈がされて
さらには「所有権の複製」なんていうトンデモ説が出現しちゃう

545デフォルトの名無しさん2022/01/13(木) 14:09:36.75ID:O06YpWsI
>>543
ownershipが所有権ならtransferは譲渡
move(移動)とは明確に使い分けられてる

546デフォルトの名無しさん2022/01/13(木) 14:28:13.33ID:LRlvXHH5
結局はどこにも原典がないオレオレ用語でワロタ
技術は研鑽していかないといけないのに
ポエムと独自解釈と拡大解釈によって逆方向に突き進むボンクラ

547デフォルトの名無しさん2022/01/13(木) 15:21:48.48ID:4OU2rK55
まぁ、オープンソースですらねぇし専門家の目すら通ってない様なサイトだし
それっぽい事書いときゃいいんだよってのが大抵のweb界隈

itで何か知りたいなら手っ取り早い話公式ドキュメント当たれって事だろ(´・ω・`)

548デフォルトの名無しさん2022/01/13(木) 15:31:14.25ID:iHsQmzfW
それでわかりやすくなるんなら別にいいけど、余計わかりにくくしてるってさぁ。。

549デフォルトの名無しさん2022/01/13(木) 15:55:36.32ID:k/BdCeDW

550デフォルトの名無しさん2022/01/13(木) 16:12:14.47ID:VN3LqOp5
ルー語で言うと「ownershipがtransferされることをmoveって呼ぶ」的な?

551デフォルトの名無しさん2022/01/13(木) 16:19:48.57ID:VN3LqOp5
this is known as a move.
英語のほうだと「ムーブとして知られています」か

実際コンパイラのソースみてもownershipはtransferとかtakeっていう表現でmoveだのcopyとは言ってないね

552デフォルトの名無しさん2022/01/13(木) 16:53:50.81ID:qAhzUFbZ
>>549
公式リファレンスくらいは英語で読もうよ
そんな変なサイト見てるからOwnershipの意味すら取れなくなるんだぞ

553デフォルトの名無しさん2022/01/13(木) 17:08:41.31ID:2BXAobev
>>552
それは変なサイトではなくRust公式ページの日本語訳。
元のRust公式ページでも同様。

Ownership and moves
https://doc.rust-lang.org/rust-by-example/scope/move.html

Because variables are in charge of freeing their own resources,
resources can only have one owner.
This also prevents resources from being freed more than once.
Note that not all variables own resources (e.g. references)

When doing assignments (let x = y) or passing function arguments by value (foo(x)),
the ownership of the resources is transferred.
In Rust-speak, this is known as a move.

554デフォルトの名無しさん2022/01/13(木) 17:27:36.08ID:W1ZKAEcb
>>553
Google翻訳にかけてごらんw
主語も目的語も受動態の意味もわかってないような翻訳はゴミ

555デフォルトの名無しさん2022/01/14(金) 00:21:00.58ID:hAOjwXhX
DeepL で翻訳してみた

なぜなら、変数は自身のリソースを解放する役割を担っているからです。
リソースは一人のオーナーしか持つことができません。
これはまた、リソースが複数回解放されるのを防ぐためでもあります。
すべての変数がリソースを所有するわけではないことに注意してください(例:参照)。

代入(let x = y)や関数の引数を値で渡す場合(foo(x))。
リソースの所有権は移転する。
Rustの用語では、これを「移動」と呼びます。

556デフォルトの名無しさん2022/01/14(金) 00:30:32.83ID:hAOjwXhX
「所有権の複製」とか、意味の分からない事を書いている、香具師がいるのか?

557デフォルトの名無しさん2022/01/14(金) 00:36:35.57ID:kUhlpB/h
>>556
!Copyの場合は所有権がtransferされるのであれば
Copyの場合はどう表現すべきかという話

558デフォルトの名無しさん2022/01/14(金) 02:45:20.76ID:InXswW/0
>>557
元の値の所有権はそのまま、複製された新しい値の所有権が新しく発生する。
元の値の所有権について何も操作は行われておらず、表現すべきことも無い。

5595562022/01/14(金) 03:32:18.88ID:hAOjwXhX
所有権が複製されるという書き方よりも、むしろ、

primitive を含むコピー型変数は、コピーされると、
所有権は移動しないので、元の変数にもアクセスできる、みたいに使う

コピーされると新たに、別のオブジェクト(実体・メモリ領域)と所有権が作られるとか

560デフォルトの名無しさん2022/01/14(金) 08:35:26.86ID:8BRe3wDd
- 所有権ごと複製するという表現がわかりやすいかわかりにくいか⇒人それぞれ
- 所有権を複製するという表現が逆になにか問題を生ずるか⇒今のところ挙げられてない

561デフォルトの名無しさん2022/01/14(金) 08:46:30.94ID:y5w5F0v6
>>556
そう
「水素の音」みたいなもん
「水素の音」って言いたい人がいるだけ

562デフォルトの名無しさん2022/01/14(金) 09:28:53.08ID:n8eH8EkW
>>558
これだよな

563デフォルトの名無しさん2022/01/14(金) 09:48:26.29ID:20065uel
所有権の複製では意味が通らない事は明らかなので、
誰か >>489 の文をサクッと直してくれていいんだぞ

564デフォルトの名無しさん2022/01/14(金) 09:59:56.29ID:wd6QtXqe
流れ見てると「所有権の複製」は

おかしいから使うな派が半分
おかしいけどまあ好きにすれば派が半分
おかしくない派が約1名

みたいな感じ?

565デフォルトの名無しさん2022/01/14(金) 12:13:02.65ID:8BRe3wDd
この生産性のない議論に参加している人の割合と考えればさもありなん。

566デフォルトの名無しさん2022/01/14(金) 12:25:28.10ID:kUhlpB/h
>>564
どうでもいい派が抜けてる

567デフォルトの名無しさん2022/01/14(金) 13:03:41.15ID:bXd4RL2X
>>560
全く別の所有権なんだからコピーとか言うとわかりにくいだろ。

568デフォルトの名無しさん2022/01/14(金) 21:39:59.21ID:+ggCJzG3
所有権というか、ポインタなのか、実体なのかって考えれば所有権もすぐに理解できると思うが

569デフォルトの名無しさん2022/01/14(金) 22:02:26.42ID:hgiR/8Zn
>>568
それは所有権を理解してないのでは?

570デフォルトの名無しさん2022/01/14(金) 22:22:42.07ID:8BRe3wDd
>>:567
1つだったものが2つになることを複製と呼ぶのはべつにわかりにくいとは思わんがなぁ

571デフォルトの名無しさん2022/01/14(金) 22:37:39.46ID:WRwvxAen
現実のものに例えると適する例がないけど
近い分野だとOSでのプロセスのfork()に近いかな
どちらも初期状態は同じでその後は別の道を歩んで値(メモリ)が別の値を取れるようになる
これをプロセスの複製と呼ぶから複製という単語自体はわかりやすいと思う

572デフォルトの名無しさん2022/01/14(金) 22:45:21.62ID:bXd4RL2X
>>570
だから「所有権」に関しては全く別物だろうがよ。。いつまでアホなこと言ってんだか。

573デフォルトの名無しさん2022/01/14(金) 22:49:30.67ID:IfPg31YF
ジエンさんも複製されてるねw

574デフォルトの名無しさん2022/01/14(金) 22:54:57.45ID:k9ZagSOx
>>570
所有権は複製はできないが分割は可能
共有名義の不動産持分みたいなやつ
Rustに当てはめるとRcにあたる

575デフォルトの名無しさん2022/01/14(金) 22:59:38.88ID:8BRe3wDd
>>572
>だから「所有権」に関しては全く別物だろうがよ

「全く別物」という理由は?2つになるのは変わるまい。

576デフォルトの名無しさん2022/01/14(金) 23:04:12.94ID:8BRe3wDd
>>574
人それぞれだと思うが俺は所有権の分割って方がわかりにくいと思うがな。
Rcと紛らわしいから「複製」は使うなというのは納得できるが。

577デフォルトの名無しさん2022/01/14(金) 23:08:16.48ID:wd6QtXqe
>>571
プロセスはtask_structとかがあってしかも実際に複製されてるからな

Rustの所有権はそういうふうに実際にstruct Ownership;みたいのが有るわけじゃない
上の方でも言ってるやつがいるけどborrowcheckerとかのルールや制約を所有権って概念で説明してるだけ

だからメモリ上でCopyな(=単純なmemcpyで矛盾が起きない)型が複製されりゃ新しい所有権が作られるし!Copyな(=単純なmemcpyだと矛盾が起きる可能性が有る)型なら所有権もtransferされるってだけ
そこに解釈云々だのの余地はなく複製もクソもない

578デフォルトの名無しさん2022/01/14(金) 23:11:40.41ID:Gij7VB+L
>>571
そこで言う複製は値の複製
forkしてもPIDは複製されないのと同じで所有権も複製されない

579デフォルトの名無しさん2022/01/14(金) 23:13:06.72ID:hAOjwXhX
複製という用語は、2つの実体が作られたよりも、
その2つの同値性が強調される

例えば、一卵性双生児は同一の遺伝子だから複製だけど、
二卵性双生児は複製じゃない。
単に、別々の2つの実体が発生しただけ

二卵性双生児間には同値性が無いから

ただ、文書を書いた外人は、copy を同値性という意味で使っていない

長文で説明するのが面倒くさいので、copyという短い単語で、
単に、2つの実体が作られたみたいに、気軽に使っているのだろう

だから、copyを翻訳すると複製になってしまう

580デフォルトの名無しさん2022/01/14(金) 23:23:12.29ID:b+sgeTEs
複製という訳の問題じゃないよね
「所有権のコピー」と言っても「copy ownership」と言っても何も変わらない

581デフォルトの名無しさん2022/01/14(金) 23:34:11.11ID:b8FVBfqE
PIDとか二卵性双生児とか、根拠や脈絡がない例え話が次々に出てくるのが笑える。
なんでそこまで必死なのかと。

582デフォルトの名無しさん2022/01/14(金) 23:56:50.14ID:ErNyx2qm
fork出してきたお前が言うなやw

583デフォルトの名無しさん2022/01/15(土) 00:13:28.41ID:5R4N3qYj
>>571は曲がりなりにも根拠らしきものを挙げているけど
>>578のPIDはまったくの根拠レスじゃん、
forkで複製されないものを探したらPIDが出てきたとかじゃね?

584デフォルトの名無しさん2022/01/15(土) 01:02:15.31ID:l/1QpEiq
>>570
値はそうかも知れんが所有権は新しくできたものだろ。
新しくできたものを複製ってのは変だろうが。

585デフォルトの名無しさん2022/01/15(土) 01:19:56.24ID:KOUnkRnZ
C++の例外をちゃんと扱うのは難しい、Rustのほうが簡単やろ

586デフォルトの名無しさん2022/01/15(土) 01:20:44.09ID:KOUnkRnZ
スレ間違えた
まあいいや

587デフォルトの名無しさん2022/01/15(土) 02:34:21.16ID:LQYSNqi+
>>583
そう感じちゃうのがRustの所有権を理解してない何よりの証拠なんだよなぁ

588デフォルトの名無しさん2022/01/15(土) 08:00:13.06ID:SUNY4hKu
>>587
根拠を挙げて主張しているかそうでないかの違い。国語の問題。
所有権を理解しているかどうかは関係ないんだがお前さんの読解力にも問題があるな。

589デフォルトの名無しさん2022/01/15(土) 08:48:58.88ID:MrK/oPRe
根拠があるってんなら単にrust公式から定義をひっぱってくればいいのではw
それが無いから単なる珍妙なオレオレ用語で終了なんだよこの話は
こーいう手合いをいちいち構ってると時間足りないぞ人生は短いぞ

590デフォルトの名無しさん2022/01/15(土) 09:24:09.35ID:i5tbAI8Y
>>588
複製おじさん必死だなww

591デフォルトの名無しさん2022/01/15(土) 10:37:04.68ID:SKIF+upB
もう誰か本家のissueに「CopyとMoveって何をcopy、moveしてるの?所有権のcopyっておかしい?」って突撃してこいよw

592デフォルトの名無しさん2022/01/15(土) 10:38:54.35ID:zYbpVr1V
スレ追い切れてないけど所有権だけcopy/moveしてるという主張してる人がいるの?

593デフォルトの名無しさん2022/01/15(土) 11:23:39.22ID:xPHqeDv2
>>591
聞くまでもなくおかしいだろwww
何をcopy、moveしてるのかはチュートリアル読めよ

594デフォルトの名無しさん2022/01/15(土) 11:24:43.51ID:ZhZU0a8B
>>592
複製おじさんちーっすw

595デフォルトの名無しさん2022/01/15(土) 12:21:18.07ID:NVDl8gUD
参照の説明に合わせてCopy Typeには所有権は無いという捉え方ならかろうじて理解はできる

596デフォルトの名無しさん2022/01/15(土) 13:06:56.98ID:SKIF+upB
>>593
おれら匿名の有象無象におかしいって指摘されても聞く耳持たねぇみたいだから本家でぶった切られてこいっていう皮肉なw

597デフォルトの名無しさん2022/01/15(土) 16:47:14.84ID:MrK/oPRe
Cでポインタへのポインタをダブルポインタと言い張ったり
Cで関数へポインタで値渡ししてるだけのことを参照渡しと言い張ったり
酷いと思わんかね?
思わん人も居ることのほうが問題

598デフォルトの名無しさん2022/01/15(土) 17:52:02.36ID:gzKdcX6j
>Cでポインタへのポインタをダブルポインタと言い張ったり
>Cで関数へポインタで値渡ししてるだけのことを参照渡しと言い張ったり
c++でポインタ渡しを参照渡し言うならそりゃ誤解は出てくるが、そんなに問題にならんわ。
てか extern C で参照渡しは普通にポインタ扱いになるしな。
rustで所有権のコピー言うのは明確に意味がおかしい。

599デフォルトの名無しさん2022/01/15(土) 18:25:43.70ID:V6fKEShR
もうええやろこの話題は…こんな枝葉の問題でギャーギャー騒いでたら何も身につかんで…
Rust棒を使って気に食わないやつを殴りたいだけなんか…?

600デフォルトの名無しさん2022/01/15(土) 18:25:58.18ID:T5sD8sXT
所有権 → リソースの解放義務
コピーしたらアカン

601デフォルトの名無しさん2022/01/15(土) 19:00:19.86ID:Pt/mdzot
c++23以降で契約プログラミングのサポートが入るらしいけど、rustって言語レベルで契約プログラミングサポートしてる?

602デフォルトの名無しさん2022/01/15(土) 19:35:04.98ID:Ipn+w0vn
1週間以上も議論が続いている原因はおそらく
copyとmoveの対象の非対称性にあると思う

Copy trait非実装の型は「所有権がmoveされる」
Copy trait実装の型は「値がcopyされる」そして「新たな所有権が生じる」

603デフォルトの名無しさん2022/01/15(土) 20:06:03.10ID:gzKdcX6j
そんな複雑な理屈じゃなくてただのバカが意固地になってるだけだろ。。

604デフォルトの名無しさん2022/01/15(土) 21:12:26.97ID:U8m/+TaT
>>602
議論が続いてる気になってるんだw

605デフォルトの名無しさん2022/01/15(土) 21:34:33.77ID:5CQZXOEN
>>602
moveの対象も値だぞ
the bookのownershipの解説ページに1つでもmoveの対象がownershipになってる箇所あるか?
https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html

@ITの記事はそこも間違ってる

606デフォルトの名無しさん2022/01/15(土) 21:37:55.34ID:5CQZXOEN
>>600
ホントこれ
所有権が何かわかってれば複製なんて考えは絶対出てこない

607デフォルトの名無しさん2022/01/15(土) 21:44:00.10ID:+D8ShBal
俺は中立派なので
「Copyトレイト実装型は値と所有権が複製される」
でも構わないし9割以上の人々にはこれで通じるだろう
あとはどこまでこだわるかだけだ
これ以上その表現は容認できないと続けるならばスレ荒らしと変わらない

608デフォルトの名無しさん2022/01/15(土) 21:52:50.82ID:MrK/oPRe
>>607
「所有権の複製」は根拠の無いオレオレ用語であり
rust公式による定義は一切示されなかった

でオシマイの話
議論ですらないし
どっち派という派閥の話でもない

609デフォルトの名無しさん2022/01/15(土) 22:04:56.72ID:Ipn+w0vn
一般的に「批判や反対だけならバカでもできる」と言われるので
ここは代替案、修正案、改善案を示してはどうだろうか?

610デフォルトの名無しさん2022/01/15(土) 22:09:17.84ID:im+Hgbd+
匿名掲示板のやりとりで意見を変える人なんていないしとっとと次の話題に移るに限る

611デフォルトの名無しさん2022/01/15(土) 22:17:16.04ID:xn0tLhqJ
複製おじさんが必死過ぎて草www
自分の間違いに気づいてもなお苦し紛れの言い訳テラワロスw

612デフォルトの名無しさん2022/01/15(土) 22:29:40.11ID:SUNY4hKu
>>597
参照渡しという用語は定義があるからCのポインタ値渡しに使うのは明らかに間違いなわけだが
ダブルポインタの方は正式に仕様で規定されているわけではないが俗語として通用しているな。
俗語だから前提無しに誰にでも通じるわけじゃないというところ注意が必要だが。

613デフォルトの名無しさん2022/01/15(土) 22:30:43.34ID:daomKUdj
複製おじさんは自演して複数人を装ういつもの人

いつも間違いを指摘されるが全く反省せず
嘘を書き続けて強弁しつつ自演擁護するのが趣味
C++じいさんと一緒にここに隔離されてる

614デフォルトの名無しさん2022/01/15(土) 22:33:34.89ID:im+Hgbd+
所有権も複製されるとするとrustの所有権システム破綻するの?
そういう話ではなくて用語の用法に違和感があるという議論だよね?
理解合ってる?

615デフォルトの名無しさん2022/01/15(土) 22:44:35.60ID:Ipn+w0vn
>>614
その通り
俺は既に書いたように
『Copy trait実装の型は「値がcopyされる」そして「新たな所有権が生じる」』だが
これを『値と所有権が複製される』と表現する人がいても特に困らないしRustの理解で破綻することもない
現実にある所有権に照らし合わせると『所有権の複製』という用法に違和感があるだろうという話

616デフォルトの名無しさん2022/01/15(土) 23:04:44.12ID:psZvEbv8
>>613
今日いきなり「複製おじさん」とかいう特異な単語を使う人が立て続けに現れたんですがw

617デフォルトの名無しさん2022/01/15(土) 23:42:27.61ID:IhXEZL2k
>>614
複製されたら破綻するよ
当たり前じゃん
所有権を何だと思ってんの?
わかってないの複製おじさんだけだよ

618デフォルトの名無しさん2022/01/16(日) 10:16:15.91ID:FbMoDLfJ
>>614
>所有権も複製されるとすると

所有権は複製されない。

619デフォルトの名無しさん2022/01/16(日) 10:41:29.77ID:78YeqR3t
一週間バカにされ続けても自ら学ぼうとしないメンタルすごいよな

記事書いたやつも複製おじさんも所有権を変数単位のフラグみたいに認識してるんだよ
Copyなら変数の値をコピーして所有権フラグの値もコピーするイメージ(何か問題でも?w)

現実の所有権のように各所有権が個別リソースに紐づくと考えてないから「所有権を複製」しても問題ないと思っちゃう

所有権のメタファー台無し

620デフォルトの名無しさん2022/01/16(日) 10:49:19.61ID:78YeqR3t
>>617
>所有権を何だと思ってんの?
この質問に答えられるようなら1週間前に終わってる話
自信がなくバカにされるのが怖くて答えられない
だから自演して印象操作に走ってしまう
それで余計にバカにされちゃう悪循環

621デフォルトの名無しさん2022/01/16(日) 10:53:40.34ID:zLzfdhk5
Rustスレは

仲介イテレータおじさん
所有権の複製おじさん
算数100点おじさん

の提供でお送りします

622デフォルトの名無しさん2022/01/16(日) 10:57:58.12ID:Ew12sdpw
みんなサビサビや!

623デフォルトの名無しさん2022/01/16(日) 12:33:17.26ID:hGTA6e5C
仲介おじさんと複製おじさんは同一人物でしょ

624デフォルトの名無しさん2022/01/16(日) 14:09:05.15ID:KLhMVNjz
しょーゆー拳!の複製とは・・・所有してない事では・・・?それとも共有?創造イテレーターおじさん。。。

625デフォルトの名無しさん2022/01/17(月) 22:59:06.94ID:Y2e2eRad
Rust 1.58で使えるようになったね

let var = 123.45;
assert_eq!(" 123.450", format!("{var: >10.3}"));

let vec = (5..=9).collect::<Vec<i32>>();
assert_eq!("[5, 6, 7, 8, 9]", format!("{vec:?}"));

626デフォルトの名無しさん2022/01/19(水) 19:54:17.44ID:E5BGSNnr
rust学習してるんだけど
コンパイル時検査で並列処理の安全性(可変参照が1つである事)を証明できるんだろうか?
実行時に借用チェックが行われてるという説明があったけどそれは必要なの?

627デフォルトの名無しさん2022/01/19(水) 19:59:57.13ID:E5BGSNnr
勘違いかも
この記事実行時にチェックしてるという意味じゃないかもしれない

628デフォルトの名無しさん2022/01/19(水) 21:18:54.23ID:gQYkvdGO
>>626
複数スレッドから参照される変数はコンパイル時に保証できないから実行時に保証されるよ
Mutexとか

629デフォルトの名無しさん2022/01/19(水) 21:23:52.62ID:tIKoVln/
Rc<RefCell<T>>のように所有権が共有されてる値を変更する場合なんかは実行時チェックしかできない

interior mutability patternと呼ばれるやつはみんなそう

630デフォルトの名無しさん2022/01/19(水) 21:24:20.06ID:tIKoVln/
ガブリンチョ

631デフォルトの名無しさん2022/01/20(木) 10:26:42.45ID:O3OMKZ6x
実行時に動的に借用のチェックをさせたいという動機は分かるんだが
RefCellっていう名前でそれが表現できてると思えないし
一方で内部可変性を表現してるとも思えないし
そもそも内部可変性と実行時借用規則強制と二つのことが一つの名前になってるし
じゃあどうすべきだったということも思いつかないけど
なんかモヤモヤしてる

632デフォルトの名無しさん2022/01/20(木) 12:30:05.06ID:Rdmkjysn
Cell<T> は Mutable<T>
RefCell<T> は DynamicMutable<T>

Cellが何かを一度イメージできるようになると
今のネーミングでも困らないから名前が変わることはないと思う
interior mutabilityという名前も最初は分かりにくかった
こっちはまだ変わる可能性あると思う

633デフォルトの名無しさん2022/01/20(木) 12:40:28.40ID:z2ZQEaJV
https://internals.rust-lang.org/t/pre-rfc-rename-refcell-to-give-it-a-descriptive-name/533
議論はあったが決定的な代替案があったわけでもないみたいね

634デフォルトの名無しさん2022/01/20(木) 12:41:15.85ID:lj0NmUaq
あー、なるほど、名前が分かりづらいのはおれが日本人のせいなのかな、とか思ってたけど、やっぱり慣れてないと分かりづらいネーミングだったか

635デフォルトの名無しさん2022/01/20(木) 13:06:17.45ID:wvPJOB1p
そもそもBoxってなんやねん!😡

636デフォルトの名無しさん2022/01/20(木) 13:18:31.58ID:hnvUf8sg
>>631
中身を書き換えられる『セル』という分かりやすい名前
Cellは内部可変がOK
RefCellは内部可変参照がOK

違いが分かりやすいように3種類を持つ構造体を用意
struct S {
a: [i32; 3],
c: Cell<[i32; 3]>,
r: RefCell<[i32; 3]>,
}
let s = S {
a: [1, 2, 3],
c: Cell::new([1, 2, 3]),
r: RefCell::new([1, 2, 3]),
};
// s.a = [4, 5, 6]; // コンパイルエラー (sがmutじゃないため)
// s.a[1] = 5; // コンパイルエラー (sがmutじゃないため)
s.c.set([4, 5, 6]); // OK 内部可変
{
let mut p = s.r.borrow_mut(); // OK 内部可変参照
p[1] = 5;
// このブロックを抜けるとborrow自動返却
}
assert_eq!([1, 2, 3], s.a);
assert_eq!([4, 5, 6], s.c.get());
assert_eq!([1, 5, 3], *s.r.borrow());

637デフォルトの名無しさん2022/01/20(木) 13:20:34.04ID:O3OMKZ6x
メソッド名が動的←→静的と対称的であったりもしないし・・・

Cell: get, get_mut, set
RefCell: get_mut, borrow, borrow_mut

ただしget_mutはそれぞれ
https://doc.rust-lang.org/std/cell/struct.Cell.html#method.get_mut
> this method expects self to be mutable, which is generally not the case when using a Cell.
https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.get_mut
> this method expects self to be mutable, which is generally not the case when using a RefCell.
とあり通常の用途とやらで考えると

Cell: get, set
RefCell: borrow, borrow_mut

共に"Cell"で内部可変性を表現しつつ
用途はメソッド名で十分わかるしまぁもういいのかこれで

638デフォルトの名無しさん2022/01/20(木) 13:27:05.24ID:O3OMKZ6x
>>632
>>636
Cellっていう短い名前にクッキリした役割を描いたのはRust陣営は成功かもね
Rust以前に前例があるかどうかは知らんけど

>>634
名前の説得力が不足してる疑いはあるよね

>>635
それなw

639デフォルトの名無しさん2022/01/20(木) 13:39:18.98ID:hnvUf8sg
>>637
Cell⇔RefCell は 静的⇔動的 の関係ではない
Cell⇔RefCell は 直接⇔参照 の関係
そのため余分にRefが付く

静的⇔動的 の関係にあるのは
「&」⇔「RefCell::borrow()」)
「&mut」⇔「RefCell::borrow_mut()」

640デフォルトの名無しさん2022/01/20(木) 13:52:05.11ID:O3OMKZ6x
>>639
少なくとも構造体の説明としては

https://doc.rust-lang.org/std/cell/struct.Cell.html
> A mutable memory location.

https://doc.rust-lang.org/std/cell/struct.RefCell.html
> A mutable memory location with dynamically checked borrow rules

↑のように書いてあるね
だから
SCell // A mutable memory location with statically checked borrow rules
DCell // A mutable memory location with dynamically checked borrow rules
こんなんでもよかったんじゃないかなぁと思ったがこれはこれで石投げられそう

641デフォルトの名無しさん2022/01/20(木) 14:13:35.66ID:hnvUf8sg
>>640
それは違う
間違った解釈で無関係な場所に「with statically checked borrow rules」を付けてはいけない

参照借用規則『multi readers xor single writer』に対して
以下が「静的チェック⇔動的チェック」の関係にある
静的チェック: multi「 &」xor single「&mut」
動的チェック: multi「RefCell::borrow()」xor single「RefCell::borrow_mut()」

一方でCellとRefCellの関係は
内部可変性が「直接書き換えOK」⇔「参照書き換えOK」の関係
だからCellに対してRef(参照)が付くRefCellという名前になっている
そして参照となるRefCellに対してのみ上述の参照借用規則が適用される

642デフォルトの名無しさん2022/01/20(木) 14:23:25.93ID:O3OMKZ6x
>>641
なるほどね

https://doc.rust-lang.org/std/cell/struct.Cell.html#method.get_mut
> If you require interior mutability by reference,
> consider using RefCell which provides run-time checked mutable borrows through its borrow_mut method.

↑ここでもまずは「参照による内部可変性が必要な場合は」と先に来てるね
「実行時に動的に借用のチェックをさせたいという」のが動機だと俺勝手に思いこんでたけど
それは一番じゃないみたい

643デフォルトの名無しさん2022/01/20(木) 14:32:46.88ID:XZNQ8H/m
>>635
Cell/RefCellと違ってBoxは分かりやすくていい名前だと思うぞ
Boxing/Unboxingは他の言語でも普通に使われてるよね?
旧名のOwned<T>や代替案のHeap<T>に比べると確実にいい

644デフォルトの名無しさん2022/01/20(木) 14:45:20.72ID:nm3lJD8v
Boxing/UnboxingはC#やJavaにもあるからBoxには全く違和感なかったけど
よく考えるとソースコード上にBoxという文字列が出現するのはRustだけかも?

645デフォルトの名無しさん2022/01/20(木) 14:54:02.35ID:3oKX7/s6
Scheme でも次の規格に Box が入ることになっている。
(既に導入している処理系も結構ある。)

646デフォルトの名無しさん2022/01/20(木) 15:32:21.48ID:hnvUf8sg
通常の型TやBox<T>などがSend+Syncである一方
Cell<T>とRefCell<T>は!Send+!Syncであることと引き換えに内部可変性を得ている
つまりmutではない参照の内部にあったとしても
「Cell<T>」は「mut T」のように成れて直接書き換え可能
「RefCell<T>」は「&mut T」を得られて参照書き換え可能
ここでCellとRefCellの違いは「&」すなわち「Ref」だからこの命名自体は分かりやすいと思う

647デフォルトの名無しさん2022/01/20(木) 16:52:16.46ID:O3OMKZ6x
>>644
むしろJava等にあるからこそ戸惑ったわ
既にあるBoxing/Unboxingへの理解に対して
Rustでは突如構造体としてBoxだもん

648デフォルトの名無しさん2022/01/20(木) 23:14:12.74ID:c3YxPrqk
まあBox と名前を合わせてBoxCellとか逆にBoxをRefにするかした方が統一的な名前づけだったとは思う。

649デフォルトの名無しさん2022/01/21(金) 07:08:34.56ID:zwVIa7Oi
>>648
Box<T>はヒープ上にTの場所を確保してそこを指し示します
Cell<T>はヒープ上かどうかは無関係で例えば>>636の使用例では全てスタック上
したがって「Boxと名前を合わせてBoxCellとか」はおかしいです

TとCell<T>はメモリ上の格納場所も実体も同じです
つまりCellとは内部可変性という特性を与え示していると考えたほうがわかりやすいでしょう
RefCell<T>も同様ですがこちらは参照借用規則の実行時チェックのためのborrowフラグが余分に確保されます

もうひとつの「BoxをRefにするかした方が統一的な名前づけだったとは思う」もおかしいです
refは参照(reference)の略としてあちこちで使われておりヒープ上かどうかは無関係ですが
Box<T>はあくまでもTがヒープ上にあることが主眼です

余談ですがこの関係でRefといえばstd::cell::Refという構造体があり
これはRefCell::borrow()が返す型として直接意識することはなく使われています
ちなみにRefCell::borrow_mut()が返す型はstd::cell::RefMutです

650デフォルトの名無しさん2022/01/21(金) 10:40:22.86ID:a7B69/kD
何も分かってねーなこいつ。
なぜBoxにするか、なぜRefCellにするかってのは要するに構造体のサイズを決定できない場合を想定してるわけよ。
スタックにそういういう動的にサイズが異なる実体をおくことも最近のコンパイラではないこともないが、通常はヒープに置くわ。
文字通りしか考えないで実際の使い方なんか一切考えないやつってのが丸わかりになるって意味では
分かってなさそうなやつにこの辺りについて問いただすってのは割と良いかも。

651デフォルトの名無しさん2022/01/21(金) 11:50:08.61ID:ePel1TKs
皆の言ってることがよくわからん
そもそもBoxとRefCellって対比させるようなものか?

652デフォルトの名無しさん2022/01/21(金) 12:13:07.97ID:a7B69/kD
T -- Box<T>
Cell<T> -- RefCell<T>
って普通に考えれば対比させると思うけど。

653デフォルトの名無しさん2022/01/21(金) 13:03:50.49ID:ePel1TKs
RefCell<T>はTへのrefが作れるCell (実行時にborrow checkする)
TとBox<T>はborrowに関しては同じ振る舞いでデータの場所がヒープか否かの違い
全然関係性違うと思うんだけど

654デフォルトの名無しさん2022/01/21(金) 16:26:46.26ID:HthXViD+
>>653>>649は合っている
>>650は間違っている
BoxとRefCellには共通点も類似性も関係性も何もない

655デフォルトの名無しさん2022/01/21(金) 16:43:50.31ID:9uS/kBRP
「所有権の複製」がおかしいってことは納得言ってくれたん?w

656デフォルトの名無しさん2022/01/21(金) 23:30:48.05ID:HnzI5Wog
表現の問題だけど別にいいんじゃね?

657デフォルトの名無しさん2022/01/22(土) 00:49:37.07ID:FWRR5JB/
ダメです
明らかにおかしい
ポインタ渡しと参照渡しを間違えてるくらいにはおかしい

658デフォルトの名無しさん2022/01/22(土) 01:05:08.77ID:7E1QrPk4
それは解釈のレイヤの問題。
JIS の情報処理用語の定義では参照呼び (参照渡しという言葉は定義がないが実質的に同じだろう) はオブジェクトの場所を渡すことと定義されていて、
ポインタという形で場所を渡すのも参照呼びの一種ということになる。
言語仕様の話をしているところで異なるレイヤが混ざるのはおかしくはあるが、
実例を示そうとしたり、逆に抽象的に説明しようとしたりすると境界が曖昧になることはある。

659デフォルトの名無しさん2022/01/22(土) 19:22:08.25ID:1QIe2ldW
じゃああなたはポインタ渡しと参照渡しを間違えてもいいよ

660デフォルトの名無しさん2022/01/22(土) 19:59:43.90ID:n0owABsu
>>658
ポインタ渡しと参照渡しが同じなら、nullptrを渡すのと同じことを参照渡しでどうやるか教えてくれ。

661デフォルトの名無しさん2022/01/22(土) 20:05:58.29ID:DSkywrpw
>>657
参照渡しじゃなくてダブルポインタの方だろ。

662デフォルトの名無しさん2022/01/22(土) 20:32:06.98ID:9yXjOkuN
ポインタ渡しっていう用語も使わないでほしい
ポインタ型の時に特別なもんでもなんでもなく
他の場合と同じcall by valueなのだから

663デフォルトの名無しさん2022/01/22(土) 20:53:17.10ID:vfyV6CZn
rustにおいて参照渡しと言ったらどういう意味になるんだろうか

664デフォルトの名無しさん2022/01/22(土) 22:32:38.62ID:g0imoAcW
>>657
そんなレベルじゃないだろw
「値の参照外し」くらいのありえねーやつだぞ

665デフォルトの名無しさん2022/01/22(土) 23:03:41.04ID:bh/4ELt7
>>663
&Tを渡すこと

666デフォルトの名無しさん2022/01/22(土) 23:09:33.04ID:j/zdYx9z
>>654
>BoxとRefCellには共通点も類似性も関係性も何もない
そうそう、何の共通点も類似性も関係性もないのに
The BookではBoxとRefCellを対比させてどういうケースにどっちを使うかわざわざ解説してるんだよなぁ
何の共通点も類似性も関係性も無いにも関わらずw

667デフォルトの名無しさん2022/01/22(土) 23:45:04.56ID:YZScTEQ/
>>666
マジでその二つは関連も類似も何もない
大きく分類してもBoxはスマートポインタの一種だが
RefCellはスマートポインタではなく内部可変性という性質の指定のみ

668デフォルトの名無しさん2022/01/23(日) 00:16:51.00ID:GGOFm3A0

669デフォルトの名無しさん2022/01/23(日) 01:50:05.66ID:N2HN4NXS
clippy様がvoldemort typeを説明せよと仰せなのだが
もしかして、名前を言ってはいけないあの人のことをご存じない?

>>668
そこはinterior mutabilityの前提としてborrowing rulesを
おさらいするためにBoxを出してるだけだから違うだろ。
多義的なオレオレ用語が多くて質は悪いけど
the bookに意味もなくBoxとRefCellを登場させてる章なんてなかったと思う。

670デフォルトの名無しさん2022/01/23(日) 09:58:49.85ID:I/0ReqFd
なんでわざわざ自演するのかね?

671デフォルトの名無しさん2022/01/23(日) 10:23:00.27ID:pcY9kzKW
それが仲介おじの悪癖なんよ

672デフォルトの名無しさん2022/01/23(日) 14:04:42.46ID:Tw7cio1+
病気だな
病名は知らんけど

673デフォルトの名無しさん2022/01/23(日) 15:19:04.05ID:Qjn377p7
rust勉強しはじめたばかり、C,C++はだいぶ昔少し経験がある程度

Cとかじゃ、constなpointerは、変数自体がconstと、指ししめす対象自体がconstである場合があり
const T * const p;
みたいな宣言があったが

Rustはデフォルトでイミュータブルなのはわかるけど、mutを付けると、変数自体も指し示す対象もmutableになってしまう?

let mut v = vec![1, 2, 3];
v.push(2);
v = vec![4,5,6];

どっちか一方を禁止する方法とかあるのですか?

674デフォルトの名無しさん2022/01/23(日) 17:38:28.44ID:v0FQj8Ao
C上がりのヤツって意味のないところにconst付けがち
関数の引数にconst DWORD vとか

675デフォルトの名無しさん2022/01/23(日) 19:54:52.69ID:GGOFm3A0
>>673
どういうことをしたいのかによるけど
let x = Vec![...];
let mut y = &x;
みたいにすればyは再代入可能だけどxやvecの中身は変更不可になる

676デフォルトの名無しさん2022/01/23(日) 20:02:24.55ID:N2HN4NXS
末尾oとかWとかで荒らしてるやつ回線なんだ?亡霊か?

677デフォルトの名無しさん2022/01/23(日) 20:58:37.79ID:sgP3cX+L
えっ、一人二役まだ続けるのか

678デフォルトの名無しさん2022/01/23(日) 22:45:59.41ID:N2HN4NXS
お前Lはないだろ

679デフォルトの名無しさん2022/01/23(日) 23:46:00.51ID:QpDxG2zZ
ちなみにRustでのconstとはコンパイル時点で定数(どんな複雑な型でもよい)であること
プログラミング言語によってはconstなのに実行時に決まる値(がその後変化しないこと、つまり単なるimmutable)を意味しているので意味の差に注意

680デフォルトの名無しさん2022/01/23(日) 23:59:31.12ID:2V1gRdrY
>>674
Rustでは関数の引数にconstはないな
ジェネリクスとしてのパラメータにはconstがありこちらは便利

681デフォルトの名無しさん2022/01/24(月) 00:27:06.65ID:bSZB9aci
>>675
ありがとうございます。
やりたいことは、だいたい同じですけど、少し違って
v.push(2)か再代入のv= vec![4,5,6];のどちらかを禁じたいでしたけど
あなたの投稿みて考えて

let v = &mut vec![1, 2, 3];
v.push(2);
//v = vec![4, 5, 6]; エラーになる

で一応できました。
でも再代入可能で、中身変更不可にvをする方法は思い浮かびませんでした。
675のようにして、vからyに代入したらyはそうなりますが。

682デフォルトの名無しさん2022/01/26(水) 20:11:49.47ID:IHm+4QQV
すまんが、Replit使って学習してるんだけどさ
たまたま海外勢の動画見たら、同じReplitのはずなのに波線の指摘とかコード補完とか効いててびっくりしたわ


うちではこんなのならないんだけど・・・・やり方わかる人いたら教えてくれんかな?

683デフォルトの名無しさん2022/01/26(水) 22:40:12.84ID:e2k0MxNT
Repl.itは、リンターやデバッガーからサードパーティのパッケージ、ホスティング、デプロイまで、

すべてを備えた、ブラウザー内の完全な共同クラウド開発環境です

684デフォルトの名無しさん2022/01/27(木) 14:52:35.89ID:kmz9k/kc
プログラミングRustの第2版の訳書出たんだな

685デフォルトの名無しさん2022/01/27(木) 17:03:59.04ID:O/Xb3RdK
t

686デフォルトの名無しさん2022/01/30(日) 18:39:19.14ID:Np8aVX2s
Rustはゼロ除算はコンパイルエラーになるの?

687デフォルトの名無しさん2022/01/30(日) 18:46:47.93ID:iWlFH2We
const文脈ならコンパイルエラーになったはず

688デフォルトの名無しさん2022/01/30(日) 19:13:28.33ID:9ei8l7Ku
コンパイル時に判明しないゼロ除算やオーバーフロー除算 ex. -128_i8 / -1_i8 はpanicとなるので
それが困る場合はchecked_div()を使えばOption型が返りNoneとなる

689デフォルトの名無しさん2022/01/30(日) 20:48:51.55ID:iWlFH2We
>>688
ほんとだ、定数式じゃなくてもエラーになるんだね
https://play.rust-lang.org/?version=stable&;mode=debug&edition=2021&gist=78efbd7a2e6ac42c15da2cfb0d11485f

即値じゃなくてもエラーにしてくれてある程度賢そう
https://play.rust-lang.org/?version=stable&;mode=debug&edition=2021&gist=381372577a28207f3a37bc007ac6e29c

690デフォルトの名無しさん2022/01/30(日) 21:12:48.50ID:2J0C/Vn/
const fn divide(x:i32, y:i32) ->i32 {
x / y
}

let x = divide(1, 0); //panic
const y: i32 = divide(1, 0); //compile error

691デフォルトの名無しさん2022/01/31(月) 00:45:03.08ID:wgfsi16C
>>690
定数式の文脈でゼロ除算起きるとコンパイルエラーになるのはある意味当然だと思うんだけど
そうじゃないところでエラーになるのが意外だった
デバッグビルドでもMIRの最適化とかで定数畳み込みみたいなことやってるのかな

692デフォルトの名無しさん2022/01/31(月) 07:35:21.99ID:qlFEomu1
>>691
Rustではconst fnな関数を使ってconstな定数を作ることができる
つまりコンパイラがその定数を算出するためコンパイル時点で判明する

693デフォルトの名無しさん2022/01/31(月) 10:25:13.89ID:y6tOo2ii
とあるデータフォーマットを扱うライブラリを作っています。
一定形式のレコードが連続で書き込まれて最後には終端レコードが書き込まれるという単純な形式です。
Rust 上でもレコードを追加するのと終端処理のふたつのメソッドがあるだけです。
要は ↓ のように使えるライブラリだということです。

let mut file = File::create("file.hoge").unwrap();
Hoge::new(&mut file).add_entry("string1")?.add_entry("string2")?.finish();

このとき
・ 終端処理は必ずしたい
・ 終端処理はエラーの可能性もあり、それは捕捉したい (ので drop でさせられない)
という制約を静的に表現できるでしょうか?

現状では終端処理のメソッドが実行されたときにフラグを立てておいて
drop 内でそのフラグを検査するという形にしています。
可能ならコンパイル時に発見できるようにしたいです。

694デフォルトの名無しさん2022/01/31(月) 11:02:40.38ID:qlFEomu1
エラーを捕捉したいことをデストラクタに任せない
つまりそのような終端処理はdropされる前に終える
例えばBufWriter利用時も終える時は明示的にflushを呼ぶ
そしてflushはResultを返しエラーが判明する

695デフォルトの名無しさん2022/01/31(月) 11:32:28.54ID:LhFaS6j7
finishの呼び忘れを静的に捕捉したいということだからflushの例では不十分かな
add_entryの戻り値型の暗黙のdropを防げばいいけど、そういった機能はまだない(RFCにはあるけど進んではない)

https://users.rust-lang.org/t/prevent-drop-at-compile-time/20508
このスレッドではdropの実装に存在しないC FFI呼び出しを書いておいて、リンクエラーとして捕捉する方法が提案されているね

696デフォルトの名無しさん2022/01/31(月) 11:35:46.57ID:y6tOo2ii
>>694
それを制約として表現できるか (終端処理をしていないときにエラーになるように制約を書けるか) という質問をしてる。
つまり出来ないってこと?

697デフォルトの名無しさん2022/01/31(月) 11:53:47.47ID:y6tOo2ii
>>695
それは残念。

言語の機能として用意されてないまわりくどい方法を使うと
エラーメッセージがよくわからん (本来の問題とは違う内容が出てくる) ことになりがちだし、
使うときに unsafe や forget をいちいち書いてもらわなきゃならないのは
ライブラリとして提供するときにはちょっと汚すぎるなぁ。

698デフォルトの名無しさん2022/01/31(月) 12:37:43.75ID:pXNCEmdM
PhantomType的な?

699デフォルトの名無しさん2022/01/31(月) 12:39:21.72ID:pXNCEmdM
エラーメッセージがよくわからん事になりがちだからNGか

700デフォルトの名無しさん2022/01/31(月) 12:47:03.61ID:qlFEomu1
>>696
なるほど
コンパイラは解析してdropさせるべき位置を把握しているから
そこへ至る全ての経路上で例えばFinalize trait実装型はそのメソッドfinalize()を呼んでいないとコンパイルエラーとなる
というような制約をするFinalize trait
が存在していれば要望を満たす?

701デフォルトの名無しさん2022/01/31(月) 13:15:16.14ID:wgfsi16C
>>692
非const fnについての話なんだけど

702デフォルトの名無しさん2022/02/01(火) 18:21:42.44ID:EUosKgIx
amazon primeの記事経由でegui見てみたが結構いいな
ネイティブで試してみたが充分実用レベル

703デフォルトの名無しさん2022/02/01(火) 21:04:57.74ID:YxH4csZd
GCは標準からは消えたけどライブラリでやればいいってかつてこのスレで言われたことがあるのだが、GCライブラリのデファクトスタンダードってどれだ

704デフォルトの名無しさん2022/02/01(火) 21:52:48.48ID:noSg7Gj9
>>703
デファクトなんてあるわけないじゃん
マークスイープGCするならRust使う意味ないんだから

705デフォルトの名無しさん2022/02/01(火) 22:04:01.37ID:YxH4csZd
>>704
いや一部だけGC欲しい時は普通にあるからそれは言い過ぎ

706デフォルトの名無しさん2022/02/01(火) 22:51:54.30ID:l+/c7OlD
クッソ身につまされる記事があったので共有する
https://dystroy.org/blog/how-not-to-learn-rust

707デフォルトの名無しさん2022/02/01(火) 23:11:34.83ID:rVnoodM/
>>706
これはいい記事だな
次からテンプレ入り希望

708デフォルトの名無しさん2022/02/01(火) 23:23:08.93ID:rLXhSAw+
>>702
eguiは毎回60fpsで全画面を描き直すことで差分描き直しを避けて簡単にしてるようだけど
省力化したい方針と合わないや
ゲーム向き?

>>705
GC使ってもRustのRAIIを無くせるわけじゃないから
そういう時はVecに入れて使って
あとは任意のタイミングで未使用の要素の区画を再利用という感じにしてる

>>706
Rustは各種bookを読んであとはstd docとreference見ながら
コンパイルエラーの通り直すだけで何とかなるから書かれている通りだね
付け加えると基本要素については覚えていないメソッドのために回り道しがちなので
Option Result slice str Iteratorあたりの全メソッドは一通り認識しておくといいかな

709デフォルトの名無しさん2022/02/02(水) 10:20:38.88ID:OC/eznuR
複製おじは自分では何とかなってると思ってるのか

710デフォルトの名無しさん2022/02/02(水) 11:48:12.13ID:yXsdGz3O
🐜蟻型蜂🐝はポジティブシンギング🤯だから

711デフォルトの名無しさん2022/02/02(水) 18:24:25.46ID:LUGaOk8s
>>706
>Mistake 3 : Start by implementing a graph based algorithm
その通りだとは思うけどRustと相性の良いアルゴリズム集的なのは欲しいとも思う

712デフォルトの名無しさん2022/02/02(水) 19:18:50.51ID:aYiI+nmg
>>711
汎用データ構造の大部分を使うな、という話になりそうだからなぁ。
スタックとキューくらいは楽に使えるのかね。

713デフォルトの名無しさん2022/02/02(水) 20:06:31.96ID:9W9+AwqU
dynや lifetime heavyは失敗しながら学ぶのでいいと思う
普通の人はしばらくやってれば気づくから

714デフォルトの名無しさん2022/02/02(水) 20:34:19.12ID:ljjcfSf9
deny(rust_2018_idioms)はガチのマジでオススメです

715デフォルトの名無しさん2022/02/02(水) 22:05:12.51ID:cdYzXGt/
データ構造が大事なんだって言われながら育ってきた身としちゃあ辛い話じゃねえか

自分で作らなけりゃいいんだな!ってslab_tree使って
「ある条件に合致した子ノードから、ルートまでの値をリストで取り出す」
みたいな処理を書こうとしたら怒られるんだよな。
node_ref.parent() : &Self<T> -> Option<NodeRef<T>
っていう型なもんだから、次々に親をたどるために
while Some(parent) = node.parent() { node = parent; ...}
みたいな処理書くと、当然怒られる。

何とか抜け道無いかって探したら、node自身じゃなくてそのIDを使えばよかったんだけど、
いつも抜け道があるとは思えない。辛い。

716デフォルトの名無しさん2022/02/02(水) 22:39:17.87ID:O+j3A95O
Rustで普通にやってるとスレッドセーフを強いられるから制約がキツくなるんだよね

717デフォルトの名無しさん2022/02/02(水) 22:41:53.47ID:J71gX0gE
大昔からの単純なポインタ相互参照だと
ダングリングポインタ・多重解放・解放忘れなどが全く存在しないことを検証すべき範囲が一般的には広くなりすぎる
もし狭い範囲に閉じ込められるケースならば閉じ込めた中でunsafeを用いたとしても効率的な型を提供すればよい
標準ライブラリにあるヒープを用いる型は全てそのようにして作られている

718デフォルトの名無しさん2022/02/03(木) 23:00:23.96ID:KgH5nhZs
>>684
今それ読んでる
出版物だけあって日本語の質はずっといい

719デフォルトの名無しさん2022/02/03(木) 23:17:16.89ID:VxNIdQ9k
Craterについて教えてください

720デフォルトの名無しさん2022/02/04(金) 00:50:00.86ID:Ueb60Gjp
>>718
もしかしてThe Bookの勝手訳の質と比べてる?

721デフォルトの名無しさん2022/02/04(金) 21:15:13.65ID:fCF+Tqbd
>>720
勝手訳というのがなにを指すのか不明だけどオリジナルのThe Bookからリンクされている日本語訳のことであればそれと比べている

722デフォルトの名無しさん2022/02/04(金) 21:21:32.40ID:b3SZZj/4
そんなのを見るのは極初期だけで些細な話
その後はdoc.rust-lang.orgとdocs.rsしか見ないのだから

723デフォルトの名無しさん2022/02/05(土) 13:22:14.88ID:XET6D0Ck
その極初期の人が見る和訳の質の話をしてるんだろ

724デフォルトの名無しさん2022/02/05(土) 14:41:30.63ID:e42LAXmg
あれは害悪レベルの訳だから初期でも見ない方がいいよ
ここでよくおかしなレスしてる人もあれの影響なんじゃないか?

725デフォルトの名無しさん2022/02/05(土) 15:12:20.92ID:WBcMnxrA
どうせ>>722のドキュメント見ないと先へ進めないしほとんどは中学生でもわかる平易な英語
日本語訳の質にこだわるような低レベルのやつはほっとけばいい

726デフォルトの名無しさん2022/02/05(土) 15:52:33.91ID:2hiBx8fY
Mistake 2 : Dive in without looking at the book

727デフォルトの名無しさん2022/02/05(土) 15:59:05.92ID:WBcMnxrA
>>726
まさにそれで最初は日本語訳でもいいがその後にthe bookを直接見るべき
そしてどの英単語でどう表現されているかを掴めば日本語訳がどうかに関わらず先へ進める

728デフォルトの名無しさん2022/02/05(土) 16:02:12.98ID:2hiBx8fY
>>727
言ってること変わってますけど

729デフォルトの名無しさん2022/02/05(土) 16:03:52.79ID:WBcMnxrA
一貫してるぞ
日本語訳の質にこだわるような低レベルのやつはほっとけばいい
これしか主張していない

730デフォルトの名無しさん2022/02/05(土) 16:09:07.88ID:2hiBx8fY
そこ以外の文章はポエムか何かだったの?

731デフォルトの名無しさん2022/02/05(土) 16:22:12.93ID:XET6D0Ck
じゃあ和訳の質を話題にしている低レベルの人同士の会話はほっとけばいいのにw

732デフォルトの名無しさん2022/02/05(土) 17:02:52.76ID:VkrSTqtm
日本語イラネ言っている人は技術資料が英語でも
日本語でも生産性が変わらない人なんだよね?
アメリカの仕事でもした方が稼げるんじゃない?

733デフォルトの名無しさん2022/02/05(土) 17:05:29.47ID:nog/R4+C
和訳の質にこだわってる人たちも唯一役に立つチャンスがあるよ
それは和訳の改善案を提案して質の向上に貢献すること
しかし和訳の質にこだわってるここの人たちは批判だけで提案がないから残念な人たち

734デフォルトの名無しさん2022/02/05(土) 17:15:34.64ID:9gZgvarh
和訳の質にこだわっている人たちの質にこだわっている人は何の役にたつの?

735デフォルトの名無しさん2022/02/05(土) 17:36:04.99ID:XET6D0Ck
どこの食堂が美味いか話しているところに割り込んで、
不味い方を立て直してこいと言うくらいナンセンス。

736デフォルトの名無しさん2022/02/05(土) 17:36:55.75ID:Z82/7dFa
>>725
その結果、所有権を複製しちゃったんでしょw

737デフォルトの名無しさん2022/02/05(土) 17:58:18.58ID:oHTbhGZf
とはいえ元の話は
無料の炊き出しがレストランより不味い
みたいな話なのでそりゃそうだろうとしか
誰もがオライリーを気軽に買えるわけでもないし
それぞれ意味はあるだろう

738デフォルトの名無しさん2022/02/05(土) 18:14:45.46ID:9gZgvarh
ざんねんながら悪文どころか誤訳だらけで無料の炊き出しよりひどいのがままあるのが技術書の世界

739デフォルトの名無しさん2022/02/05(土) 18:19:44.18ID:nog/R4+C
>>738
誤訳だと言うなら改善案を提案して質の向上に貢献するのがいいよ
それができないなら単なるイチャモン付けるだけの残念な人

740デフォルトの名無しさん2022/02/05(土) 18:40:50.96ID:SfaxLljQ
クソ不味い飯屋にわざわざ改善案を提案するやつww
「批判するなら対案出せ」と同じアホ理論www

741デフォルトの名無しさん2022/02/05(土) 18:44:43.09ID:NEwj3nV7
両立するよ。
改善に取り組みつつ現時点では良くないところもある (信頼しすぎるな) と初心者に警告するのは何も矛盾しない。

742デフォルトの名無しさん2022/02/05(土) 18:55:08.74ID:RA3mCqKO
>>741
>両立するよ。
何と何が両立するの?

743デフォルトの名無しさん2022/02/05(土) 19:15:32.20ID:9gZgvarh
>>739
ではイチャモン付けるだけの残念じゃない君が俺の代わりに改善案を提案しておいてくれ

744デフォルトの名無しさん2022/02/05(土) 19:38:56.71ID:nog/R4+C
>>743
自分は現状の和訳で問題ない派
そんな些細なことよりも和訳だけでなく原文も併用した方がよく
その後は原文だけの世界なのだから

745デフォルトの名無しさん2022/02/05(土) 19:43:44.48ID:9gZgvarh
なんだ、日本語が読めない人だったか

746デフォルトの名無しさん2022/02/05(土) 19:50:42.02ID:WBcMnxrA
日本語訳の質にこだわるような低レベルのやつはその先へ行けないため日本語訳にこだわる

747デフォルトの名無しさん2022/02/05(土) 21:53:27.09ID:tUU0u0u/
複製おじさんが言っても説得力ゼロ

748デフォルトの名無しさん2022/02/05(土) 22:32:09.49ID:nog/R4+C
和訳にイチャモン付けるだけの残念な人は「複製おじさん」を連呼する人でしたか

749デフォルトの名無しさん2022/02/06(日) 10:19:03.76ID:rpYaxfPG
>>543からの流れを見ると確かに複製おじさんは英語読めないっぽいが
Copyを「所有権の複製」と思い込むのは日本語訳の質が原因ではない気がする

750デフォルトの名無しさん2022/02/06(日) 21:49:38.13ID:iA9Wv++J
そんな超初心者入門のところでもめてるのかね
trait Copyを実装している型は複製されて、実装していなかったら移動となるだけだぞ
所有権は難しくない

751デフォルトの名無しさん2022/02/06(日) 21:58:58.41ID:nXnmaz3p
>>750
何が複製されて
何が移動するのかな?

752デフォルトの名無しさん2022/02/06(日) 22:11:28.10ID:BkoYcqr9
>>489 の文章が間違ってる、いやおかしくない、って揉めてただけだよ
まあ気付けば普通はおかしいと思うんだけど

753デフォルトの名無しさん2022/02/06(日) 22:13:32.98ID:iA9Wv++J
>>751
所有権
Copy実装型は常に所有権が分岐する

754デフォルトの名無しさん2022/02/06(日) 22:39:23.39ID:JXWBQEX4
>>753
複製(copy)と分岐(branching)は全く違う意味だけどCopy実装型だと所有権が複製されつつ常に分岐する??
どういう意味?

755デフォルトの名無しさん2022/02/06(日) 22:43:41.39ID:iA9Wv++J
>>754
初期状態は全く同じ
つまり複製されて分岐する
それ以降は異なりうる

756デフォルトの名無しさん2022/02/06(日) 22:57:43.95ID:VdsOdvUM
Rustの所有権というのは権利というよりも所有しているリソースの解放義務を指している
複製できたら所有権管理の意味がない
分岐はもっと意味不明

757デフォルトの名無しさん2022/02/06(日) 22:59:53.55ID:9tkt2bmo
489から始まった議論をまたやり直すの?

758デフォルトの名無しさん2022/02/06(日) 23:01:30.97ID:s1W7Zv37
複製おじさんが分岐して所有権分岐おじさんにw

759デフォルトの名無しさん2022/02/06(日) 23:04:45.50ID:iA9Wv++J
>>756
複製され分岐するため
リソース解放義務はそれぞれに生じる

760デフォルトの名無しさん2022/02/06(日) 23:09:58.47ID:Woj/yg4T
>>759
複製おじさん、嘘ついちゃダメだよ
詳しくはdoc.rust-lang.orgとdocs.rs見てねw

761デフォルトの名無しさん2022/02/06(日) 23:26:57.07ID:kRmD/jh4
複製おじさん連呼する人は、もちっと具体的に指摘してくれるとありがたいんだが。

762デフォルトの名無しさん2022/02/06(日) 23:31:49.27ID:iA9Wv++J
嘘ではない
もちろんCopy実装型の時点でヒープは使われないので解放といってもスタッフ上のみだから実質何も行われない
そのためデストラクタも容認されていない
その観点からCopy実装型は所有権がないと主張する人もいるくらいだ

763デフォルトの名無しさん2022/02/06(日) 23:59:50.68ID:fxuI+J0l
>>761
おじさんを連呼してる人はスレを荒らしているだけのクズ
説明や代案や根拠などを語れない

764デフォルトの名無しさん2022/02/07(月) 00:00:24.28ID:eBqtDcmM
>>762
何も行われないのに複製されて分岐してそれ以降は異なりうるってどういうことだよ

矛盾だらけ

765デフォルトの名無しさん2022/02/07(月) 00:09:06.68ID:sOY0eIf2
>>761,763
複製おじさん得意の自演乙www
嘘つきは分岐の始まり

766デフォルトの名無しさん2022/02/07(月) 00:19:43.65ID:+QREW3s6
> そんな超初心者入門のところでもめてるのかね
> 所有権は難しくない

【超初心者向け所有権の説明】
Copy実装型は所有権が複製されて分岐してそれ以降は異なりうる

難しくないw

767デフォルトの名無しさん2022/02/07(月) 00:23:15.30ID:A0JQeUWh
>>764
この件は有名な話でRustコンパイラのサボり。
Copy型は複製分岐されて各々がdropされるのが正しいけど、スタック変数のみだからそれをサボっている。
つまり現在のコンパイラ実装は正しくなくて、dropしちゃうとサボりのせいでメモリunsafetyを引き起こす可能性がある。
だからCopy型はDropを現状では許していないという話。
rustc --explain E0184 を見てね。

768デフォルトの名無しさん2022/02/07(月) 01:29:41.70ID:6Fl/+EdH
>>767
なんか仕様と実装を混ぜて話してるけどなんで?
普通、仕様にそって実装がされるはずだけど、(この部分に関しては)実装に仕様が引きずられてるってこと?
それとも仕様通りではないってこと?

769デフォルトの名無しさん2022/02/07(月) 08:04:57.91ID:cIffYd5J
>>725
順調に滅びの道を歩んでいるな。

770デフォルトの名無しさん2022/02/07(月) 12:36:41.09ID:E3rdzbcC
将来実現されるであろうあるべき仕様が実装の都合で実現できていないから、それと矛盾しない範囲に仕様の範囲を制限した、という理解で良い?

771デフォルトの名無しさん2022/02/07(月) 13:38:44.35ID:ZeQEvlq1
>Copy型は複製分岐されて各々がdropされるのが正しいけど、スタック変数のみだからそれをサボっている。

まーた勝手な思い込みの妄想で嘘垂れ流してる
いい加減にしろ

772デフォルトの名無しさん2022/02/07(月) 18:29:28.92ID:lRQrpp2a
>>767
それ1.0以前の話で今とは実装も前提も全く違うからエラーメッセージ修正したほうがいいやつ

もし仮にDropかつCopyな型が実装できるようになったとしても所有権は複製されないから

773デフォルトの名無しさん2022/02/07(月) 21:58:52.41ID:pvg7UzFi
>>768
「currently disallowed」「current implementation is incorrect」「disabled for now」と強調されてるように、
あくまでも現在の実装は本来とは異なり正しくなくて、問題を引き起こすために、CopyとDropの両立を現時点では禁止してる。
理論的にはCopy型は複製分岐されて各々がdropされる形が正しくてCopyとDropの共存が可能。
この暫定的な実装に引きずられた暫定的な仕様が、将来は正される可能性も残す表現となっている。
両立禁止で実害が出てないため優先順位は低いと思われるが、もし将来に共存可能になったとしても後方互換性は生じない。

>>772
最新のエラーメッセージで合っている。
https://github.com/rust-lang/rust/blob/master/compiler/rustc_error_codes/src/error_codes/E0184.md
Latest commit 9e5f7d5 on 28 Aug 2020

774デフォルトの名無しさん2022/02/07(月) 22:27:06.61ID:zI1SZbAO
>>773
>理論的にはCopy型は複製分岐されて各々がdropされる形が正しくて
複製分岐されるのが正しいという根拠は?

775デフォルトの名無しさん2022/02/07(月) 22:38:57.39ID:pvg7UzFi
>>774
Copyなので複製分岐されるのは当たり前。
今はそこが論点ではなくて、複製分岐の後に各々に解放処理が生じるけど、現在は正しく実装されていないので仕様に制限があるとコンパイラのメッセージでも出る話。

776デフォルトの名無しさん2022/02/07(月) 22:50:06.68ID:3WtW5B3R
>>774
複製分岐おじさんは日本語通じないからまともに相手しても時間の無駄だよ

777デフォルトの名無しさん2022/02/07(月) 22:52:45.27ID:MLiEvPiI
「最新のエラーメッセージ」は1.0直前に書かれたものだしもう仕様化してもいいんじゃね
https://github.com/rust-lang/rust/pull/25272

778デフォルトの名無しさん2022/02/07(月) 23:03:21.13ID:jZIVUuZq
いつも傍から見ていてパターンがわかってきた
普通は「○○○は間違っている、×××が正しい」となるんだけど
なぜか「○○○は間違っている」だけで終わって代わりとなる対案が出てこない
>>771のように「勝手な思い込みの妄想で嘘」と否定するだけだったり
>>774のように「正しいという根拠は?」とこれも同じパターン
全てに共通するのは対案を出さずに否定ばかりしている言動

779デフォルトの名無しさん2022/02/07(月) 23:11:42.66ID:gOCxugwW
>>775
今は複製分岐されるのが本当正しいと言えるのかどうかが論点です
論点をずらさずにそう考えた根拠を示して下さい
ありませんか?

780デフォルトの名無しさん2022/02/07(月) 23:15:03.65ID:Rl6UL3Q6
半ギレww

781デフォルトの名無しさん2022/02/07(月) 23:28:02.69ID:q/PrVpBp
>>777
仕様化されてるよ
エラーメッセージをアップデートすべき
https://doc.rust-lang.org/reference/special-types-and-traits.html#copy

その時代とはDrop周りの実装も大きく変わってる上に
CopyとDropが排他的である前提で書かれたコードも多々あるから
Copy+Dropな型をサポートするならエディション対応が必須

782デフォルトの名無しさん2022/02/07(月) 23:45:39.09ID:jZIVUuZq
>>779
Copyを実装している型は使われると複製され分岐すると自分も当たり前に思っているけど
異なる意見を持っているの?
否定ばかりしていて対案を出せない人はどこの世界でもダメな人扱いになっちゃうから対案を出すのがお勧め

783デフォルトの名無しさん2022/02/07(月) 23:54:38.63ID:MLiEvPiI
>>781
まじかよ反応して損した
この流れ何の意味もねえな

784デフォルトの名無しさん2022/02/08(火) 00:13:43.96ID:6pYzzNS7
Copyを実装する型の変数にはそもそも所有権が存在しないということかな。

785デフォルトの名無しさん2022/02/08(火) 00:58:18.89ID:v5+/0O15
ソケット、ファイルハンドラあたりがコピーされたらそら問題だろうからな。

>Copyを実装する型の変数にはそもそも所有権が存在しないということかな。
copyされたら所有権がないとかめちゃくちゃだな。int値だって共有されるかどうかはかなり問題だっての。

786デフォルトの名無しさん2022/02/08(火) 01:23:08.03ID:Ie+ZA5Wx
>>782 値が複製されることに異論は無いんだけど、彼は>>753などで所有権が複製されると言っていて、そこがおかしい。

787デフォルトの名無しさん2022/02/08(火) 02:46:17.65ID:TlrfCSTD
それ同一人物だぞ
複製オジは人格も複製分岐させる

788デフォルトの名無しさん2022/02/08(火) 09:41:57.74ID:SQntNedJ
たとえ話って逆に理解を妨げることも多いよね(´・ω・`)

789デフォルトの名無しさん2022/02/08(火) 10:46:53.27ID:VdD2swgy
複製おじさんにも唯一役に立つチャンスがあるよ
それはE0184の改善案を提案してRustの質向上に貢献することw
しかし複製おじさんは妄想だけで改善が見られないから害でしかない

790デフォルトの名無しさん2022/02/08(火) 17:39:21.77ID:L87aFEFb
複製おじさん大人気だな
個人的には「所有権が分岐する」のほうが衝撃的だった

791デフォルトの名無しさん2022/02/08(火) 18:04:38.67ID:wY99dkVo
Rustの学習してるのですが、モジュールがどう使われるものなのかいまいち想像がつきません
他の言語でいう、スタティッククラスのような使い方になるのですか?
クレート内部にはモジュールを通じてアクセスしてもらうような、アクセサーのような感覚でいいのでしょうか?

792デフォルトの名無しさん2022/02/08(火) 18:41:34.13ID:7ZuunrUW
なんで所有権が複製分岐なんていう言葉を発明しちゃうんだろな
実際に所有権をツリー構造みたいなものでイメージしてるのかな

793デフォルトの名無しさん2022/02/08(火) 18:50:29.41ID:Pp1mAPfQ
>>791
モジュールはコードのかたまりでnamespaceを構成するもの
Javaならパッケージ、C#ならnamespace

794デフォルトの名無しさん2022/02/08(火) 20:18:25.32ID:RxI0yA8a
複製は値と所有権のペアがまるごと複製されるというイメージでわからなくもないが分岐は本当によくわからない

795デフォルトの名無しさん2022/02/08(火) 20:23:01.17ID:SvZbCMDW
>>792
何事も正しく理解できないクセがついてて
同時に、そんな自分を客観的に理解できてないから
独自用語乱発になんの違和感もないんやろな

796デフォルトの名無しさん2022/02/08(火) 20:32:05.71ID:SvZbCMDW
複おじの悪いとこは反省が無いところ

797デフォルトの名無しさん2022/02/08(火) 20:41:11.90ID:l2NSRb44
複製おじさん自演認定連呼の人も大概だけどな
技術について語るスレなんだから個性を出すな与えるな

798デフォルトの名無しさん2022/02/08(火) 22:11:02.29ID:4v8i4qWv
変数毎のメタデータに所有権管理のためのフラグか状態変数があってその値も複製されるイメージだったんでしょ
それを匂わせることを確か書いてた気がする

仮にそういう実装だったとしてもそのメタデータ自体は所有権じゃないんだけどね
複オジは反省して分岐して欲しい

799デフォルトの名無しさん2022/02/08(火) 22:15:39.64ID:F0zgFFgG
>>784
Copyを実装する型の変数にも所有権は存在するぜ
使われるたびに複製されて別々の所有権になる
例えば借用ルールなどもそれぞれ個別に適用されるようになる

800デフォルトの名無しさん2022/02/08(火) 22:17:35.77ID:HAxbJIeP
複製おじさんホントに反省しないなぁ

801デフォルトの名無しさん2022/02/08(火) 22:36:36.51ID:SvZbCMDW
複おじはまずコテハンかトリップつけてほしい
名無しに紛れ込んでスレ荒らすのやめてほしい

802デフォルトの名無しさん2022/02/08(火) 22:47:22.11ID:NtAny2QZ
>>799で合ってると思う私も何か勘違いしてる?
もし違うならば正しい情報を知りたい

803デフォルトの名無しさん2022/02/08(火) 22:54:07.50ID:DXXwh4pM
>>802
複オジいい加減にして!

804デフォルトの名無しさん2022/02/08(火) 23:05:22.58ID:6pYzzNS7
>>803
指摘の中身が無いから何をどうすればいいか傍から見てさっぱりわからんのだが。

805デフォルトの名無しさん2022/02/08(火) 23:17:16.63ID:NtAny2QZ
>>804
それそれ
おじとかオジとか言ってる人の書き込みを遡って見ても中身がないかコピペばかり
おじとオジをNGにすればよいのかな

806はちみつ餃子 ◆8X2XSCHEME 2022/02/08(火) 23:24:36.35ID:d+fT+XiK
>>802
正しいよ。 >>799 で正しい。
値が複製されると同時にそれぞれが所有権を持つというのは根本的な原理そのもの。

807デフォルトの名無しさん2022/02/08(火) 23:33:11.39ID:50t+w5HT
おや

808デフォルトの名無しさん2022/02/08(火) 23:35:38.19ID:50t+w5HT
「所有権が複製される」のではなくて、「値が複製されるとき、複製された値には新しい所有権が生まれる」と表現すべき、ってこと?

809デフォルトの名無しさん2022/02/08(火) 23:37:06.33ID:NtAny2QZ
>>806
ありがとう
おじオジ連投の人はNGにします

810デフォルトの名無しさん2022/02/08(火) 23:45:07.26ID:Gazi17ea
単なる揚げ足取りでしょ
本人もよくわかってないと思われ

811デフォルトの名無しさん2022/02/09(水) 00:09:26.69ID:hQLH/4Iv
はちみつ複製オジは自演するのいい加減して!!

812デフォルトの名無しさん2022/02/09(水) 00:48:50.88ID:Th41z547
>>799,802,806
799は言葉足らずだと思う。

>>808 のがより合ってる。

813デフォルトの名無しさん2022/02/09(水) 01:28:22.38ID:G66vCctx
あちこちでrustおじさんが暴れてるんだけどこのスレでも暴れてんのな

814デフォルトの名無しさん2022/02/09(水) 07:46:27.70ID:MYXFjZ5a
>>808
その2つの解釈に何の違いがあるのってことだよな

815デフォルトの名無しさん2022/02/09(水) 08:16:52.91ID:RoPbijrN
論理性がない、客観性もない、実績もないのに上から目線の奴いるよね
素人相手にマウント取りたいアフィブロガーやアフィチューバーの類なんだろうけど

816デフォルトの名無しさん2022/02/09(水) 08:33:26.39ID:XHPTdDLm
>>812
「言葉足らず」だっだという事にしたいのねw

817デフォルトの名無しさん2022/02/09(水) 13:00:04.34ID:v0CQAsq5
所有権を実装の観点からだけ見た場合はCopy型に所有権は(設定されて)ないと考えるのは妥当
説明用の概念として見た場合はshared referenceを除くCopy実装型にも所有権があってコピーされた際にその値に対する新たな所有権が発生すると考える方が妥当

公式は基本的に後者

818デフォルトの名無しさん2022/02/09(水) 15:18:47.99ID:06jFMmW0
>>808
「所有権が複製される」という言い方は
単なる表現の問題として矮小化されるものではなく所有権という概念を根本的に誤って解釈してるのが大きな問題

それを吹聴するのはRust入門者の学びを妨害する行為なので叩かれてる

819デフォルトの名無しさん2022/02/09(水) 18:04:35.96ID:WRBpfbxt
>>818
所有権という概念はどう解釈すべきなの?

820デフォルトの名無しさん2022/02/09(水) 18:57:48.48ID:Th41z547
>>819
辞書で調べたら?

821デフォルトの名無しさん2022/02/09(水) 19:23:18.18ID:WRBpfbxt
https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html
Ownership is a set of rules that governs how a Rust program manages memory.

rust の定義では ownership はルールのことを指している?

https://dictionary.cambridge.org/ja/dictionary/english/ownership
the fact that you own something

辞書的な定義ともまた違うようだ

822デフォルトの名無しさん2022/02/09(水) 19:30:35.55ID:WRBpfbxt
TRPLの説明では take ownership という表現も登場するし辞書的な意味で ownership が使われているのでルールのことを指すだけではないようだ

823デフォルトの名無しさん2022/02/09(水) 19:43:45.64ID:WRBpfbxt
Each value in Rust has a variable that’s called its owner.
...
The ownership of a variable follows the same pattern every time: assigning a value to another variable moves it. When a variable that includes data on the heap goes out of scope, the value will be cleaned up by drop unless ownership of the data has been moved to another variable.

このあたりの記述を読む限り、すべての値は owner となる variabke を持つ (variable が値の ownership を有する) と表現して良いように思う

対象はすべての値なので、 Copy を実装した値にも当然 owner と ownership が存在する

なので、

let a = 1;
let b = a;

という式があった場合、aは1という値のownershipを持つし、bはaの値のコピー(1という値のコピー) のownershipを持つことになる
a の持つ ownership と b の持つ ownership の関係性をどう表現すべきか、というのが議論の対象という理解で良いかな?

824デフォルトの名無しさん2022/02/09(水) 20:01:24.42ID:WRBpfbxt
aという変数が持つ1という値とそのownershipがまとめて複製されてbに渡されると思えば、owenershipの複製という言葉も不自然ではないように思う

複製といいつつ own する値や owner となる変数が異なることに違和感を持つ人がいるのもわからんでもないが、
この構造は Box<T> の clone と同じなので、
clone を複製と呼ぶのであれば、 ownership も複製されるものとして間違いではないと思う

初学者向けの説明として適当かという議論は別途必要だとは思うけども

825デフォルトの名無しさん2022/02/09(水) 20:11:57.38ID:Sh3dorK1
それは単に値のコピーですやん
値が複製されてるだけですやん
bは複製された値のオーナーになってるだけですやん
aの所有権はどこにも複製されてないですやん

826デフォルトの名無しさん2022/02/09(水) 20:45:07.16ID:y0eUGeWz
>>824
> 値とそのownershipがまとめて複製されてbに渡されると思えば
その仮定が偽。

827デフォルトの名無しさん2022/02/09(水) 20:46:37.31ID:y0eUGeWz
ていうか仮定にすらなってない。論点先取。
https://ja.wikipedia.org/wiki/%E8%AB%96%E7%82%B9%E5%85%88%E5%8F%96

828デフォルトの名無しさん2022/02/09(水) 20:47:07.42ID:bzZIRbp2
>>824
Box<T>のcloneと同じなら
どうしてownershipも複製されることになるの?
2つの繋がりがよく分からない

829デフォルトの名無しさん2022/02/09(水) 20:49:21.34ID:vm2ezt88
>>827
なるほど
こういうの論点先取と呼ぶのか
勉強になった

830デフォルトの名無しさん2022/02/09(水) 21:05:16.82ID:uQPdms8/
オーナーシップの説明にオーナーシップを使っているのか
なるほど論外だ

831デフォルトの名無しさん2022/02/09(水) 21:22:51.45ID:DXyGa46n
所有権をCopyするって書くのをやめて、値をCopyする、にしてくれればそれで済むのに、なぜ所有権の複製を正当化しようとするのか

832デフォルトの名無しさん2022/02/09(水) 21:42:23.99ID:MYXFjZ5a
べつに値をコピせずに所有権だけコピーするとか言っているわけでもなし、そんなに問題かね?

833デフォルトの名無しさん2022/02/09(水) 21:52:08.47ID:Sh3dorK1
>>832
正当性を訴えるのはやめたん?w

834デフォルトの名無しさん2022/02/09(水) 21:58:09.12ID:Th41z547
>>824
だからー、値が複製されて所有権が新規にできるんだってば

835デフォルトの名無しさん2022/02/09(水) 21:58:48.91ID:p5i5ajWp
let a = 1; は値1の所有権をaが持つということ
ここでその値1の所有権を複製してしまうと、同じ値の所有権を持つ人が複数存在してしまうことになる
let b = a; で実際に起きるのは、値1のコピーとして値1'を生成し、その所有権をbに割り当てている
値1と値1'は数値としては同じに見えるとしても違う値であって
それぞれ別々に所有権がある

1'の所有権が1の所有権の複製である、という理解は
権利書をコピーして記名欄だけ書き換えるみたいな
イメージなのかもね
実際にはその記名欄が所有権の全てであって、
複製する部分というのは存在しない

836デフォルトの名無しさん2022/02/09(水) 22:01:53.64ID:pUgNKLbu
Copy実装型にも所有権はあって借用ルールに従う
そして使われる時に値と所有権は複製されて別々の値と所有権になる
そのため借用中だと複製できない
let mut a = 123;
let a1 = &mut a;
let b = a;
*a1 = 345;
println!("a={a}");
println!("b={b}");
例えばこのコードは借用中のため複製できずコンパイルエラー

837デフォルトの名無しさん2022/02/09(水) 22:02:09.07ID:p5i5ajWp
複製するという言い方は、複数の権利者が
(一時的にでも)存在し得るという理解につながるので
単に言い方の問題ではなく避けたほうがいいと思う

838デフォルトの名無しさん2022/02/09(水) 22:06:52.22ID:f/eR1VAb
どうでもいいならそれでいいんだけどね
中身の無いどうでもいい話をしましたってことで

839デフォルトの名無しさん2022/02/09(水) 22:10:36.37ID:zSJbpp9s
>>836
そういうことか!
値だけなら複製できてもよいのに
値と所有権が複製されるために借用中だと複製できないわけか

840デフォルトの名無しさん2022/02/09(水) 22:23:03.85ID:pUgNKLbu
その通り
だから「(所有権と関係なく)値が複製されて、その値に新たな所有権が生じる」よりも
「値と所有権が複製されて、別々の値と所有権になる」の方がRustを正しく理解できる

841デフォルトの名無しさん2022/02/09(水) 22:24:43.45ID:HWZXFj3+
wwww
複製オジのエクストリーム解釈で自演してもモロバレやでwww

842デフォルトの名無しさん2022/02/09(水) 22:35:06.54ID:MYXFjZ5a
>>835
現実世界から借用した用語は多いけど、意味まで完全に同じとは限らないからその議論は無意味だね。
そもそも現実世界の「複製」は「同じものを新しく作ること」だしw

843デフォルトの名無しさん2022/02/09(水) 22:35:22.01ID:oiWhDOci
OwnershipのルールとReferenceのルールが整理できてないんだね
分かった気にならずに一からやり直したほうがよさげ

844デフォルトの名無しさん2022/02/09(水) 22:47:52.82ID:RvxtckJm
>>836
めちゃくちゃな解説でびっくり!!
複製おじさんはこのレベルだったか

845デフォルトの名無しさん2022/02/09(水) 22:55:19.94ID:zSJbpp9s
>>844
僕は>>836の説明で納得した
そして実際にコンパイラエラーも確認した
君がそれを違うと言うならば
どの部分がどういう理由でどのように違うのかを皆に示さなければならないと思う

846デフォルトの名無しさん2022/02/09(水) 22:56:27.31ID:qfxIxGcm
>>836
それはmut借用中の値は使用禁止(コピーのために値を読み取るのも当然禁止)ってRustの基本ルールに違反してるってだけで
所有権の複製なんて新たな概念を持ち出す必要はないと思うが
実際エラーメッセージもそう書いてあるし

847デフォルトの名無しさん2022/02/09(水) 23:03:08.10ID:pUgNKLbu
>>846
借用中の値が使用禁止は所有権が伴っているからこそ生じるルール
だから「(所有権と関係なく)値が複製されて、その値に新たな所有権が生じる」よりも
「値と所有権が複製されて、別々の値と所有権になる」の方がRustを正しく理解できる

848デフォルトの名無しさん2022/02/09(水) 23:11:40.68ID:qfxIxGcm
複製派の人って複製元の所有権と複製先の所有権の
共通部分はなんだと考えているの?
流石に共通部分が全くなければ複製とは言わないよね?

849デフォルトの名無しさん2022/02/09(水) 23:20:26.95ID:pUgNKLbu
>>848
同じ型で複製の直後の値が同じものに対する所有権
全く異なるものに対する所有権が新たに生じるわけではない
所有権も複製されている

ちなみに現実のものに例える話はナンセンス
なぜなら現実世界では土地の所有権だけでなく土地自体も複製できないのだから

850デフォルトの名無しさん2022/02/09(水) 23:23:34.30ID:DXyGa46n
じゃあ「所有権」って言葉を使うのもやめることを提案してみたら?

851デフォルトの名無しさん2022/02/09(水) 23:30:03.48ID:kQ1Azr/o
>>849
土地は複製できないけどそれの何が問題なの?
値として見るならCloneじゃない型と同じじゃないの?

852デフォルトの名無しさん2022/02/09(水) 23:33:43.18ID:Av5orTrB
>>848
これ知りたいね

単に引っ込みがつかなくなってるのではなく
真剣に複製されると思っているのであれば
何らか共通部分があるんだろうから

853デフォルトの名無しさん2022/02/09(水) 23:36:33.39ID:qfxIxGcm
>>849
そうすると所有権という情報には、型と値が含まれてるってこと?
その場合、値の変更は所有権の変更を伴うと考えている?
また、型と値が同じものはたくさんありうるけど、それらの所有権を区別するものはなに?

854デフォルトの名無しさん2022/02/09(水) 23:36:49.81ID:zSJbpp9s
リアルな世界では土地もその所有権も複製できないけど
こちらの世界では値も所有権も複製できる
と考えるだけで矛盾なくRustを理解できると思います
そこに矛盾はありません

855デフォルトの名無しさん2022/02/09(水) 23:38:50.10ID:IW3Xziq4
こまけえこたあ良いんだよ!! コンパイラ黙らせた奴の勝ち!!

856デフォルトの名無しさん2022/02/09(水) 23:41:48.23ID:MYXFjZ5a
>>852
それぞれ固有の値を持たないのであれば全部同じ「所有権」では?

857デフォルトの名無しさん2022/02/09(水) 23:48:17.20ID:Th41z547
>>847
>「値と所有権が複製されて、別々の値と所有権になる」
別々のものになってて複製?
言ってて変だと思わんの?

858デフォルトの名無しさん2022/02/09(水) 23:49:17.89ID:DXyGa46n
そもそも発端は入門者向けドキュメント >>486 にて、「所有権の複製(コピー)」とかいう言葉が出てきてこれではダメだ、っていうのが発端だからね
入門者向けドキュメントなんだから、正しい言葉で、正しく伝わる表現をしてほしいのよ

859デフォルトの名無しさん2022/02/09(水) 23:50:31.60ID:MsecEarl
結局のところ元の記事にあったように
「所有権とは、文字通り変数が値を所有できる権利のことです。」と間違って捉えてるってことだろうな

860デフォルトの名無しさん2022/02/09(水) 23:56:24.02ID:pUgNKLbu
>>858
それは正しいだろ
少なくともその解釈でRustの仕様と矛盾する点は何もない

861デフォルトの名無しさん2022/02/09(水) 23:57:32.97ID:wC50dlGN
>>856
ん、これどういう意味?

862デフォルトの名無しさん2022/02/09(水) 23:59:13.88ID:MYXFjZ5a
>>861
Unit型みたいな。

863デフォルトの名無しさん2022/02/10(木) 00:04:56.40ID:ERwpat+E
土地は複製できないって主張もよくわからなくて
例えばコピー機は別に原子レベルで複製しているわけでもなく
人間が見て同じに見える程度に見た目を再現してるだけなわけで
同様に土地だって同じ形状に造成できるわけじゃん

だから複製というときにはオリジナルのどこを再現したかが重要で
何が共通部分で何が差異なのかをはっきりしてほしい

864デフォルトの名無しさん2022/02/10(木) 00:06:24.62ID:TkQE8lES
>>857
複製ってのがそもそも別のものを作ることなんだが

865デフォルトの名無しさん2022/02/10(木) 00:39:11.50ID:lkU+MWHi
所有権っていう"もの"がある訳じゃないよ?

866デフォルトの名無しさん2022/02/10(木) 01:01:15.29ID:ZN2u8Rs1
リソースの所有者はリソースを解放する責務がある
主としては値が変数に束縛されることで所有の関係が作られる

このへんをいろいろひっくるめて所有権の概念になるわけで、こういった概念である「所有権」そのものを複製したり作成するというのは、やはり言葉としておかしい

束縛関係を複製とか言われても意味わからん

867デフォルトの名無しさん2022/02/10(木) 01:05:28.97ID:TkQE8lES
ここで"もの"かそうでないかを区別する意味ってある?その場合の"もの"ってなに?

868デフォルトの名無しさん2022/02/10(木) 02:44:56.84ID:rtSKPHyc
所有権とは所有にまつわるルールのことというのはTRPLに書いてある通りだと思うんだが
take ownership など、所有権という物をやりとりしているように読める文言はどう解釈すれば良いんだ?

869デフォルトの名無しさん2022/02/10(木) 03:18:42.60ID:748mZL+w
所有権の話はもう禁止してくれ、唾飛ばしながら「ワイが一番所有権分かってるぞ!」とかほんまどうでもいいわ
コンピューターサイエンス学科出でもないのに、もう駄コードを書く仕事に戻れ

870デフォルトの名無しさん2022/02/10(木) 04:10:06.01ID:ZV1iYxPB
>>868 が言ってる通り公式ドキュメントと矛盾がないように書くべきでしょ
そうすると、copyするのはvalueであって、ownershipはcopyしない
ownershipはtakeしたりtransferするもの

>>866 の最初に書かれてることは良いけど、そのあとは意味不明

871デフォルトの名無しさん2022/02/10(木) 05:39:51.83ID:LZ4lXgTU
この自演おじさん、そこらじゅうで同じ芸風で荒らし回ってるから本当にタチ悪い。

872デフォルトの名無しさん2022/02/10(木) 07:56:52.23ID:B7Nnq//K
結論:
「所有権の複製」は根拠の無いオレオレ用語であり
rust公式による定義は今回も一切示されなかった

でオシマイの話

873デフォルトの名無しさん2022/02/10(木) 08:16:17.16ID:lkU+MWHi
このおじさん普通に統失だと思う

874デフォルトの名無しさん2022/02/10(木) 09:03:54.77ID:o2ECnsWv
>>870
これが正しい

875デフォルトの名無しさん2022/02/10(木) 10:20:54.50ID:E3cwpb32
>>868
take ownershipのownershipは”もの”じゃないよ
もうちょっと英語勉強したほうがいいんでは?

876デフォルトの名無しさん2022/02/10(木) 12:39:37.06ID:JVrcL5p7
>>875
理由を言わず間違ってるとだけ指摘して勉強した方が良いとマウントとってくるいつもの人だ
反論できないから空っぽの指摘しかできないのかな

877デフォルトの名無しさん2022/02/10(木) 12:43:51.26ID:tTxcUdMu
unixのファイルシステムの権限周りの継承とかその辺とごっちゃになってんのかね?
どうして所有権をコピーみたいな話が出てきたのかわりと謎

878デフォルトの名無しさん2022/02/10(木) 14:41:33.57ID:3wQKSQe5
謎だよな
C++から来てるわけでもないし
どこから来た発想なんだろう?

879デフォルトの名無しさん2022/02/10(木) 16:06:58.32ID:mDz1Cqyx
>>876
説明してもらっても聞く耳持たないから
もう理由は教えないみたいなことを言われてなかったか?

880デフォルトの名無しさん2022/02/10(木) 16:38:55.18ID:rtSKPHyc
>>879
その説明へのレス番号貼るだけでもいいよ

881デフォルトの名無しさん2022/02/10(木) 17:36:51.53ID:jQfqixkL
所有権ルールと参照ルールを混同してたり
所有権が複製される構造はBox<T>のcloneと同じと言ってるところに
勘違いのヒントがありそうだか皆目検討がつかない
誰か解読してくれ

882デフォルトの名無しさん2022/02/10(木) 18:29:19.19ID:1jbJS/Bn
人格複製ニキの目的って何なんだろな

883デフォルトの名無しさん2022/02/10(木) 21:15:53.35ID:HYxEyueN
所有権の複製wwwww

884デフォルトの名無しさん2022/02/10(木) 21:16:13.39ID:lQNRE6Xh
はちみつさんに直接聞いてみたら?

885デフォルトの名無しさん2022/02/10(木) 21:17:20.02ID:lQNRE6Xh

886デフォルトの名無しさん2022/02/10(木) 23:25:06.23ID:3aizDYBf
ここまで見てる限りどっちでもOKな話だな
値と所有権が「!Copy型は移動」「Copy型は複製」との説明でもRustの理解に支障がないのも事実
一方で現世界にない「所有権の複製」という表現に違和感を持つ人が存在することも理解できる
ただし後者はあくまでも心の内なる話だから前者を崩せない限り不利っぽい

887デフォルトの名無しさん2022/02/10(木) 23:34:31.44ID:o2ECnsWv
>>886
いや、>>870 で正しいの書いてくれてるのに、公式でもそうなってるのに何故に頑なに所有権の複製を広めようとしてるのよ笑食べて

888デフォルトの名無しさん2022/02/11(金) 00:20:49.53ID:05KWrNRV
語感には個人差があるからな
個人的には「複製」といえばCopyじゃなくCloneだし、Cloneなら「所有権の複製」もぎりぎり許せる
Copyを無理やり日本語にするなら「複写」かな

Copyの何たるかは
https://doc.rust-lang.org/std/marker/trait.Copy.html
で十分説明されてると思う

>>881
「ファイルの所有権がある⇒ファイルにアクセスできる」
の類推で
「変数(値)の所有権がある⇒変数(値)にアクセスできる」
と誤解されるケースはたまにみかける
これは用語(訳語)の問題でもあるから多少は仕方ない

889デフォルトの名無しさん2022/02/11(金) 00:26:11.55ID:jgApYu5Z
Rustの公式ドキュメントを調べると "copy of the value" という表現はたくさん出てくるが、 "copy of the ownership" のような表現は見つけられない
おそらく公式ドキュメントでも "copy of the ownership" みたいな言葉が使われそうになったときは意図的に排除されてるんだろう

もし "copy of the ownership" みたいに変更しても問題ないと思うなら、公式ドキュメントのリポジトリでそういうふうに提案してみてくれよ
Contributionのガイドを参考にコミュニティに書いたり、GithubでPull Requestするだけだからさ
https://rustc-dev-guide.rust-lang.org/contributing.html

890デフォルトの名無しさん2022/02/11(金) 01:40:58.50ID:3Ka4+NQm
ownership の take や transfer という言葉が出てくるのは !Copy な値についての説明で、
Copy な値については ownership 絡めて説明されてないよね
ownership rule 自体は全ての値に適用されるから本来は Copy な値の ownership についてとうルールが適用されるかという説明はあった方が良いかもね
元々の初学者向け記事ではTRPL英語版にない部分の説明をするにあたって所有権の複製という用語を発明したわけだけど
どう説明するとわかりやすいんだろうか

891デフォルトの名無しさん2022/02/11(金) 01:48:31.89ID:+uMSd1hh
>>886
>Rustの理解に支障がないのも事実
めちゃくちゃ支障が出てますやんw

所有権が複製されると思ってるからRustの基本ルールが理解できない >>836
所有権が複製されると思ってるからThe Bookの意味が取れない >>868

892デフォルトの名無しさん2022/02/11(金) 01:57:15.41ID:Bozzm6u4
>>888
Rust的には「変数(値)の所有権がある」という表現が既におかしいぞ

893デフォルトの名無しさん2022/02/11(金) 08:08:57.43ID:pt0GtJjK
>>890
> 元々の初学者向け記事では(中略)所有権の複製という用語を発明したわけだけど

オレオレ用語を初学者に平気で刷り込んで平気ならば

> どう説明するとわかりやすいんだろうか

今後一切あらゆる場所で説明などしないでほしい

894デフォルトの名無しさん2022/02/11(金) 08:18:36.04ID:pt0GtJjK
平気すぎた(ノ∀`)アチャー

895デフォルトの名無しさん2022/02/11(金) 08:49:57.52ID:IHS0l4KB
個人が複製を分かりやすいと思うのは自由だけど
初心者に広めるのはダメだと思うがな
もっと明らかに初心者向けの例え話とわかるような用語ならともかく
いかにも公式の技術用語っぽい見た目をしてるわけで
これを知った初心者がもっと深く知りたいと思ったときに
ググっても全く情報は出てこないし、誰かに質問しても「なにそれ?」ってなる
少なくとも公式の説明に沿った言い方なら、それで理解してる人が
大勢いるから、そういった問題は生じない

896デフォルトの名無しさん2022/02/11(金) 08:58:58.08ID:WRuOVQdn
自分の理解不足を何で公式の落ち度みたいにすり替えてるんだ。間違いを認めたら死んじゃう病なの?

897デフォルトの名無しさん2022/02/11(金) 10:27:57.19ID:2FzZhGyg
>>881
Box<T>が出てくるあたり所有権を値へのポインタ的なものとして考えてるのかもな
まあそれでも複製はされないからイミフには変わりないんだが

898デフォルトの名無しさん2022/02/11(金) 11:14:45.52ID:zZVxGVeC
勘違い勘違い言うけど>>808以上の話じゃないように思うんだが。

899デフォルトの名無しさん2022/02/11(金) 11:24:34.62ID:3Ka4+NQm
自分も>>808で良いと思うけど公式の説明と表現が同じになってるかは気になる

900デフォルトの名無しさん2022/02/11(金) 11:38:14.49ID:MSfgatap
>>808
>>「値が複製されるとき、複製された値には新しい所有権が生まれる」と表現すべき

だからそれが間違っている
値には所有権は無い
入れ物に対して所有権がある
例えば&mutはその入れ物に対する書き換え可能な参照つまり所有権の借用

>>808を肯定する連中はRustをわかっていない

901デフォルトの名無しさん2022/02/11(金) 11:42:56.32ID:UuEYjDqs
複製オジが遂に撤退戦をはじめたかw

なんで所有権が複製可能だと思い込んだのか説明してくれれば
他の人の役に立つのにな

902デフォルトの名無しさん2022/02/11(金) 12:01:57.67ID:3Ka4+NQm
>>900
「入れ物に対して所有権がある」も微妙な表現で
「入れ物となる変数が複製された値の所有権を持つ」の方が適当だと思うけど、どう思う?

903デフォルトの名無しさん2022/02/11(金) 12:06:36.51ID:IlhJUkFw
流れぶった切ってすまんけど質問
「借用」と「参照」の違いってなんなん?

904デフォルトの名無しさん2022/02/11(金) 12:07:10.38ID:MSfgatap
>>902
値は書き換わる物
だから値に所有権はない
入れ物に対して所有権がある
解放する対象も入れ物であってその値ではない

905デフォルトの名無しさん2022/02/11(金) 12:14:00.85ID:6AYXkq/G
>>904
c言語のfreeって明らかに値を解放してるように思えるんだが
freeした値はその後使えないがその値を入れていた変数はその後も使える

906デフォルトの名無しさん2022/02/11(金) 12:21:34.19ID:zZVxGVeC
ownerに対する所有権があるような話になってよくわからんね。

907デフォルトの名無しさん2022/02/11(金) 12:25:48.71ID:vAEawTbN
>>903
参照は変数の種類で、借用は参照の使い方とか参照同士の関係とか状態のこと。
明確に書かれていないけど、そのへんを意識してThe Bookのreferences and borrowingあたりを見ると良いよ。

908デフォルトの名無しさん2022/02/11(金) 12:44:48.12ID:MSfgatap
>>905
C言語のfreeでも入れ物を解放している
入れ物の中にある値を解放しているわけではない
そしてmalloc/freeで対象となる変数は入れ物を指している
つまりその変数自体は一つ階層が異なりポインタである
そのポインタ変数を書き換えても別の入れ物を指すようになるだけ
入れ物の中身が書き換わるわけではない

909デフォルトの名無しさん2022/02/11(金) 13:17:26.35ID:6AYXkq/G
>>908
いいえfreeは入れ物にある値を解放しています
入れ物を解放しているわけではありません
そもそもfreeに限らずc言語の関数はすべて値渡しなのでfree(入れ物)と書いたらfreeには入れ物にある値が複製されたのが引数として渡されて入れ物に関する情報は一切渡されません
c言語の関数が操作できるのはこの複製された値です
もし入れ物を関数funcで操作したい場合はfunc(&入れ物)と書きます
この場合も&入れ物という値が操作されます
繰り返しになりますがc言語はすべて値渡しなので決して関数に入れ物を渡して解放するなどと言った操作をすることはできません 解放されるのは値です
入れ物の参照を関数に渡すには&入れ物という表記を使いますが&入れ物も値です これは参照呼びと言われますがただの値渡しです
あなたは明らかにプログラミング初心者なのでこのレスが理解できるようになるまでこのスレには書き込まないでください

910デフォルトの名無しさん2022/02/11(金) 13:27:03.79ID:MSfgatap
>>909
それは君が抽象的なセマンティクスとポインタ等を介するコードの区別が出来ていない初心者だから理解できないのだろう
Rustではこの違いが特に大きいのでその区別を付けることが非常に重要

911デフォルトの名無しさん2022/02/11(金) 13:43:08.13ID:UrRCo2Y3
>>900
これは同意

何が何を所有してるのかという主語目的語を意識せずに
フワッと分かったつもりになってるからなんだろうね

912デフォルトの名無しさん2022/02/11(金) 13:45:34.76ID:HZ9j/fjC
次スレはワッチョイ付けたほうが良さそうですね

913デフォルトの名無しさん2022/02/11(金) 14:02:29.28ID:m8Gesa51
俺は初心者なのでフワッとすら分かっておらず、このスレでは一体何が議論になっているのかよく分からない。

914デフォルトの名無しさん2022/02/11(金) 14:04:16.80ID:6AYXkq/G
>>910
別に抽象的なセマンティクスでもないよ
君が言っている「入れ物」でさえ操作的意味論的にはアドレスを表す単なる「値」として表現されていることを知るべきだね
ちゃんと理論的にはどのように定式化されているのかを知らないで入れ物だとか言った自分の無知を埋め合わすために勝手に導入したオレオレキーワード使って他の人を困らせてる辺り一向に君は初心者から脱却できないと思うよ
「入れ物」(笑)なんかじゃなくて実際に使われているテクニカルタームを使うことから始めれば?
知らないの?

915デフォルトの名無しさん2022/02/11(金) 14:05:22.34ID:6AYXkq/G
学術的に使われた用語だからテクニカルタームではないな

916デフォルトの名無しさん2022/02/11(金) 14:28:40.44ID:m8Gesa51
私は何も知らない。

917デフォルトの名無しさん2022/02/11(金) 14:35:23.81ID:05KWrNRV
freeに渡すアドレス値を「入れ物」と呼ぶか「値」と呼ぶかでもめているように見える

918デフォルトの名無しさん2022/02/11(金) 14:44:41.81ID:6Qn4bKwU
>>914
その理解はおかしいよ
例えば
struct S(i32);
struct SS(i32, i32);
let i = 100;
let s = S(200);
let ss = SS(300, 400);
let a = [500, 600, 700];
この時にあなたの理解だと各変数に入っている「値」はアドレスなの?
もちろん生成コードにおいてスタック上のアドレスが用いられるのは事実だけど
Rustというプログラミング言語のレベルではそのアドレスは出てこずに抽象的に捉えるべき話でしょう

919デフォルトの名無しさん2022/02/11(金) 15:04:06.88ID:6AYXkq/G
>>918
それらの変数にはすべてそれぞれの実体が入っています
アドレスではありません
全ての「アドレス」は「値」ですがだからといって全ての「値」も「アドレス」であるとは言っていません
まずは読解力を身に着けましょう
もっと正しく理解をしましょう

920デフォルトの名無しさん2022/02/11(金) 15:18:23.74ID:6Qn4bKwU
>>919
では、あなたの主張するアドレスはどこに出てくるの?
let a = [1,2,3];
let v = vec![1,2,3];
どちらもアドレスではないですよね

921デフォルトの名無しさん2022/02/11(金) 15:28:24.64ID:6AYXkq/G
>>920
失礼しました
配列は先頭要素のアドレスが変数に格納されるでしょう
これだけで済む話です
抽象化なぞそもそも必要とされる余地はありません

922デフォルトの名無しさん2022/02/11(金) 15:36:10.19ID:H8NApfSl
所有権を持つのは値じゃなく変数
これはいいよね
オライリー本とかは少し違うけど
少なくとも公式は値が別の値を所有するとか
値が別の値の所有権を持つという考え方は採用していない

で解放のほうだけど
解放する対象はメモリ領域であって値でも変数でも無いよね
便宜的に「変数(の指してるメモリ領域)を解放する」とか
「値(が格納されてるメモリ領域)を解放する」という言い方をすることがあるだけ

923デフォルトの名無しさん2022/02/11(金) 15:46:50.29ID:MSfgatap
>>921
それも違う
配列の先頭要素のアドレスが変数に格納されているわけではない
Rustではもっと抽象的なセマンティクスでプログラミングをするし配列の長さも持つ

924デフォルトの名無しさん2022/02/11(金) 15:47:39.62ID:zZVxGVeC
値に対する所有権を変数が持つってことなら>>808は特におかしいとは思わないが?
逆に「入れ物」(変数?)に対する所有権とか言っている>>900の方が理解しにくい。

925デフォルトの名無しさん2022/02/11(金) 15:47:44.62ID:6AYXkq/G
>>922
私は操作的意味論のモデルに乗っかって表現したまでです
操作的意味論ではメモリ領域を示すアドレスは値として表現されています
ある特殊な操作的意味論で定義された理論をベースにしているRustでメモリ領域のことを値だと表現するのは間違っていないでしょう
逆に入れ物や変数だといった表現をこの文脈で使うのは言語道断かと思われます

926デフォルトの名無しさん2022/02/11(金) 15:51:44.74ID:6Qn4bKwU
>>921
それは違いますよ
そこでアドレスという考え方はしませんし、実装で見ても間違っています
例えばあなたの考えでは以下の4つの変数のうちアドレスとなるのはどれですか?
struct S(i32);
struct SSS(i32, i32, i32);
let i = 100;
let s = S(200);
let sss = SSS(300, 400, 500);
let a = [600, 700, 800];

927デフォルトの名無しさん2022/02/11(金) 15:54:42.31ID:6AYXkq/G
>>923
すいません
さらに配列の長さも保持しているのならなおさら抽象化のレベルは下がりますよね?
自分が何を言ってるのかわかっておいでですか?
もしかしてRustの抽象化レベルってCよりも下なんじゃないんですか?(笑)

928デフォルトの名無しさん2022/02/11(金) 16:01:23.79ID:VlXZAIWT
なんでこのスレでは操作的意味論とC言語とRustをちゃんぽんして語ってるの?
みんな器用だね?

929デフォルトの名無しさん2022/02/11(金) 16:02:15.20ID:6AYXkq/G
>>926
変数という用語も正しくはありません
まず第一にRustでは束縛と呼ばれます
正しく理解してください
それができないならばあなたはこれ以上スレに書き込まないでください

ちなみに私がアドレスだと言っているものはあなたが変数だと言っている物です
そもそもアドレスという表現も不適切なものですが悪しからず

930デフォルトの名無しさん2022/02/11(金) 16:21:36.51ID:MSfgatap
>>929
ついに馬脚を現したな
Rustでも変数(variable)と呼ぶことすら知らないのか
もちろん束縛(binding)も狭義の代入(assignment)と区別するために用いるが
そこでも束縛や代入の対象は変数である

931デフォルトの名無しさん2022/02/11(金) 16:32:43.51ID:6Qn4bKwU
>>929
変数という用語で合っていますよ
早く>>926の質問に答えてください
Rustでアドレスという考え方をするあなたが間違っていると明白になりますから

932デフォルトの名無しさん2022/02/11(金) 16:36:33.29ID:6AYXkq/G
>>930
Rustの用語では束縛の対象は名前です
変数ではありません
Rustが便宜的に変数と使っているのは説明のためにユーザーにRustなりに歩み寄っているからです
あなたが「入れ物」だといったよくわからないキーワードを導入したのと基本的には理由は同じです
操作的意味論では束縛の対象は変数ですが代入の対象は変数ではありません
メモリ上のある位置です
便宜的に言えばアドレスです
再三の忠告になりますが正しい理解が出来ないのであればスレに書き込まないようおすすめします

933デフォルトの名無しさん2022/02/11(金) 16:45:09.37ID:6AYXkq/G
>>931
i,s,sss,aがアドレスです
まずは>>929を理解する読解力を身に着けてください
> Rustでアドレスという考え方をするあなたが間違っていると明白になりますから

逆にアドレスという考え方をしないのですか?(笑)
手続き型言語の重要な機能ですよ?
ocamlなどと言った非純粋な関数型言語にすらありますが(笑)
アドレスという考え方を他の言語利用者が使うのを許せないのであればこの機能がないHaskellなどをご利用してくださいとしか・・・(笑)(笑)(笑)
Rustには触れないでくださいね😂

934デフォルトの名無しさん2022/02/11(金) 16:50:42.53ID:6Qn4bKwU
>>933
残念ながら>>926の変数i,s,sss,aに入っているのはアドレスではありません
あなたが完全に間違っています

935デフォルトの名無しさん2022/02/11(金) 16:56:53.29ID:6AYXkq/G
>>934
変数i,s,sss,aにアドレスが入っているなどと言ってません
読解力も理解力もないんですね
i,s,sss,aは変数ではなくてアドレスという名の値だって言うことを理解できないとあなたはいつまで立っても初心者のままですよ??(笑)

936デフォルトの名無しさん2022/02/11(金) 16:59:09.28ID:6AYXkq/G
>>934
間違っているのはあなたです
これで明白になりました

937デフォルトの名無しさん2022/02/11(金) 17:02:29.35ID:79iMdFI4
なんなんだよこのスレはw

938デフォルトの名無しさん2022/02/11(金) 17:03:16.70ID:WRuOVQdn
間違いを認めたくないおじさんが延々と言い訳するスレ

939デフォルトの名無しさん2022/02/11(金) 17:07:13.91ID:6Qn4bKwU
ID:6AYXkq/G氏は
>>919で「それらの変数にはすべてそれぞれの実体が入っています アドレスではありません」
>>921で「失礼しました 配列は先頭要素のアドレスが変数に格納されるでしょう」
これで全く理解できていないことが露呈してからさらに暴走中ですね

>>935
Rustにおいてそれらの変数i,s,sss,aはアドレスではありません
抽象的な考えが苦手ですか?

940デフォルトの名無しさん2022/02/11(金) 17:13:25.21ID:4QDnJV3g
即値とか知らなさそう

941デフォルトの名無しさん2022/02/11(金) 17:19:13.64ID:6AYXkq/G
>>939
Rustを含めアドレスという言語機能を持っている手続き型言語で変数と呼ばれているものはただのアドレスです
Rustでいう値が束縛された名前は操作的意味論における変数に対応していてあなた方がいう変数とは操作的意味論におけるアドレスを表現するものの対応物です
本来変数とアドレスは同義のものでc言語の規格で完全にポインタとアドレスが同じものとして扱われ区別されないのと同様に区別する必要性がないものです
現にポインタもアドレスも変数も操作的意味論では区別されていません
このあたりを理解できない限りID:6Qn4bKwUは永遠に初心者のままのようだ🤣

942デフォルトの名無しさん2022/02/11(金) 17:26:17.96ID:7ybYem6W
cのfreeは値「で」解放してるだけなんだけどなw
int *p = malloc(sizeof(int)); // 仮に p = 0x5617ae143260とする
free((int *)0x5617ae143260); // 値でfreeできる

値をfreeしてるわけでもなく
入れ物を解放してるわけでもなく
値をfreeに与えてやってあとはむこうでうまくヒープを解放してくれる
ヒープ解放のきっかけを値で指定してるだけ

943デフォルトの名無しさん2022/02/11(金) 17:40:06.20ID:WRuOVQdn
内部的には構造体なんだっけか

944デフォルトの名無しさん2022/02/11(金) 17:42:17.21ID:VlXZAIWT
>>941
横レスだけど
仮にこの世にコンパイラも実行するマシンもなくて、Rustのコードだけが紙に書かれてたとして
それでもi,s,sss,aは変数ではなく、アドレスという名の値だって言い張るの?
具体的にはどういう値なの?

945デフォルトの名無しさん2022/02/11(金) 17:45:23.35ID:6AYXkq/G
>>944
さあ?
実行するマシンが決まっているなら値はなんでもいいんじゃないんですか?
それこそ文字でも記号でもなんでもいい
その辺りの議論は操作的意味論の教科書で論じられていますよ

946デフォルトの名無しさん2022/02/11(金) 17:45:40.46ID:6AYXkq/G
決まっていないなら

947デフォルトの名無しさん2022/02/11(金) 17:56:17.41ID:VlXZAIWT
>>945
なんでもいいの?
書かれているコードが>>926だとして、
iの値が0x5617ae143260で
aの値が0x5617ae143260でもあなた的には問題ないってこと?

948デフォルトの名無しさん2022/02/11(金) 18:02:50.44ID:6AYXkq/G
>>947
新しいアドレスにはすでに使われているアドレスの値を使ってはいけないという制約は操作的意味論でも目にするでしょう
あなたが熱心に勉強するタイプの人であったなら私のレスを待たずにして自分で調べて自分で疑問を解決していただろうに残念ながらあなたは受動的にしか学習せず一生初心者のままに留まる人間なんでしょうね

949デフォルトの名無しさん2022/02/11(金) 18:14:14.82ID:6Qn4bKwU
>>942
その通りで、単なる識別子としての「値」で解放しているだけだね
そしてアロケーションライブラリによってはその「値」がアドレス自体でないかもしれない、と
C言語では抽象レベルと具体化レベルがほぼ一致のためアドレスが使われアドレスで考えてもいいけど
多くのプログラミング言語ではその部分は実装レベルに隠蔽されているからアドレスで考えてはよくないね

で、話を戻すと、大元の話ではその「『値で』解放している」かどうかではなくて
「『値を』解放している」のか、「なんらか抽象的な『空間を』解放しているのか」の話だったと認識してる

950デフォルトの名無しさん2022/02/11(金) 18:27:09.56ID:VlXZAIWT
>>948
ごめん、プログラミング歴20年超えてるんだわ

まあ>>947は意地悪だったけど、何が言いたいかっていうと、
有効なアドレスってのは実行時するかコンパイルしないことには定まらないでしょって話
でも言語仕様っていうのは、コンパイラが存在しなかったとしても存在し得るんだわ

で、他の人は言語仕様の話をしてるけど、一人だけ変数じゃなくてアドレスという値だって言い張るから、
マシンが存在しない状態だとどういう値なのよ?って思ったのね
意地悪なこと書いてごめんよ

951デフォルトの名無しさん2022/02/11(金) 18:35:25.52ID:7ybYem6W
おまえらって基本マジメなんやろな何か
意見の違いはあれどそんなに嫌いじゃないわ
(ただし複製おじは除く)

952デフォルトの名無しさん2022/02/11(金) 18:36:53.23ID:Y4IhV391
最適化で消えるようなもんが言語仕様なわけ無いですもんなー

953デフォルトの名無しさん2022/02/11(金) 18:39:18.92ID:6AYXkq/G
>>949
closeシステムコールはfile descriptorをcloseする
file descriptorでcloseするとは誰も言わない
file descriptorはファイルを参照する値であるがファイル自体ではない
それと同様freeはアドレスという値を解放しているのであってアドレスという値で解放してるとは誰も言わない
「値で解放するの表現が正しい」(笑)って言う意見に耳を傾けるのはまだあなたが初心者を脱することができていない証拠

https://linuxjm.osdn.jp/html/LDP_man-pages/man2/close.2.html
こういうサイトにも「close() は、ファイルディスクリプターをクローズする。」 とある

954デフォルトの名無しさん2022/02/11(金) 18:51:10.18ID:XGwZjA15
>>951
真面目すぎてひねくれたパターンだろうな
出世もしないで片隅でコード書いてる人よくいるし

955デフォルトの名無しさん2022/02/11(金) 18:51:59.28ID:6Qn4bKwU
>>952
その最適化で消えるようなもんが言語仕様
例えばRustでは言語仕様で通常の参照ポインタはnullにならない
nullを言語仕様として扱わずNone値を持つOptionを導入にしている
そしてヌルポの先へアクセスすることを完全に封じている、というのが言語仕様

ところがその抽象レベルを離れて実装レベルになると話が違う
愚直にOptionを実装すると参照ポインタ以外にメモリを余分に使う
そこで最適化によってNone時は参照ポインタの実体アドレスを0すなわちnullポインタとしている
これでOption分の余分なメモリを使わずに済ませている

つまり言語仕様としての抽象化されたレベルと
実際にアドレスがどうなるかという具体化されたレベルは常に区別しないといけない
Rustプログラマーとしては実装でどうなるかは知らなくてもプログラミングできる
そしてまずはその抽象的なレベルのみ意識して学習すべき

956デフォルトの名無しさん2022/02/11(金) 18:58:14.24ID:GB4mq7wX
>>955
こりゃ失敬。なるほど確かにそうだわ。適当な事言いましたわ

957デフォルトの名無しさん2022/02/11(金) 21:48:20.48ID:Q/4j6JIT
>>925
まーたオジさんいい加減なこと書いてるねw
操作的意味論ではvariableとlocationとvalueを明確に区別するのが一般的
メモリ領域のことを値だと表現するのはRust的にも操作意味論的にも間違い

958デフォルトの名無しさん2022/02/11(金) 21:52:44.45ID:38j0NNSx
>>941
>Rustを含めアドレスという言語機能を持っている手続き型言語で変数と呼ばれているものはただのアドレスです

全く違うんですけどwww
都合悪くなってスレ流したいのかもしれないが
とりあえず嘘八百でスレ埋め立てるの辞めてくれ

959デフォルトの名無しさん2022/02/11(金) 22:35:25.65ID:6AYXkq/G
>>957
操作的意味論ではそれ以上簡約できない項を値と呼びます
varもlocもどちらもそれ以上簡約できないので値です
試しにTaPLで値ががどのようにBNFで帰納的定義されている集合なのか確認してみたら?
あなたが理解していないだけでは?

960デフォルトの名無しさん2022/02/11(金) 22:39:32.55ID:6AYXkq/G
>>958
スレ埋めてるのはどちらかというとこのような無意味なレスをするあなたでは?
私は自分のレスが正しいと知っておりますのでどうぞ余計なレスを書き込まないでこのスレを延命してくださいませ

961デフォルトの名無しさん2022/02/11(金) 22:48:24.70ID:6Qn4bKwU
6AYXkq/Gを相手にしても無駄だから元の話に戻りましょう
>>808について自分の意見は
○「型のインスタンスに所有権がある」
×「値に所有権がある」 ←値は途中で完全に置き変わっても構わないため×
×「変数に所有権がある」 ←変数はどんどん移動できて一時的な束縛にすぎないため×
×「アドレスに所有権がある」 ←アドレスは関数へ渡したり返したり途中で変わるため×

962デフォルトの名無しさん2022/02/11(金) 23:10:21.43ID:g7TOVgtJ
>>961
「所有権がある」という意味が「所有権を持つ」という意味であれば
「値の所有者は変数」だから「所有権を持つのは変数」だよ
スコープを抜ける時に所有リソースを解放する責任というのかownershipを持つということ

型のインスタンス?
説明してもらわないと意味分からないな

963デフォルトの名無しさん2022/02/11(金) 23:19:43.49ID:rRV0mw3H
>>961
> 値は途中で完全に置き変わっても構わないため

所有権というのは「後始末する責任」のこと。
内容が書き換えられることを許すのは所有権を手放しているわけではない。

964デフォルトの名無しさん2022/02/11(金) 23:22:41.86ID:jgApYu5Z
>>961
> 「変数に所有権がある」 ←変数はどんどん移動できて一時的な束縛にすぎないため×
変数は移動できなくない? 何か別のことを言いたかったんかな?

変数が所有権を持つ、で良いんじゃないかな
値を変数に束縛するときに、変数が値を所有することになる
そして変数が値を所有したままスコープアウトすると、値をdrop(解放)する

965デフォルトの名無しさん2022/02/11(金) 23:25:49.74ID:jgApYu5Z
「変数が所有権を持つ」よりも、「変数が値を所有する」のほうがいいか

966デフォルトの名無しさん2022/02/11(金) 23:27:09.03ID:6Qn4bKwU
主語と目的語を逆に違う意味に誤解されるとわかったので補足します
○「型のインスタンスに対して所有権があるor生じる」
×「値に対して所有権があるor生じる」 ←値は途中で完全に置き変わっても構わないため×
×「変数に対して所有権があるor生じる」 ←変数はどんどん移動できて一時的な束縛にすぎないため×
×「アドレスに対して所有権があるor生じる」 ←アドレスは関数へ渡したり返したり途中で変わるため×

>>962
プログラミング言語の分野で一般的に用いられるインスタンスです
型とインスタンスは一般的に1対多の関係になります (シングルトンでは1対1ですが)
言語によっては型をクラスと表現する場合もあるようですがRustではそんな狭い範囲ではなく全ての型が対象です

>>963
そのように値は変わっていくものだから
値に対して所有権といっても曖昧さが残るでしょう
だから不変でない値に対して所有権があるとの考えはよろしくない
まだ>>964の言う変数を持ち出したほうがマシ

しかし変数との関係は一時的にすぎず所有権は別の変数へ移動していきます
所有権と常に1対1の関係にあるのは(型の)インスタンスです

967デフォルトの名無しさん2022/02/11(金) 23:32:51.77ID:rRV0mw3H
>>964
変数が所有権を持つというのは変な解釈。
結果的にはそういう挙動ではあるんだが
値が変数に捉えられている間は寿命が継続されるというルールによって
変数のスコープと連動してるだけ。
所有権を持っているのはあくまで値。

968デフォルトの名無しさん2022/02/11(金) 23:37:03.65ID:6Qn4bKwU
>>967
所有権を持っているのはインスタンスであって
値はそのときどきで変化するだけにすぎない存在だと思います

969デフォルトの名無しさん2022/02/11(金) 23:39:32.68ID:rRV0mw3H
>>968
いいえ。 そんな定義はないです。

970デフォルトの名無しさん2022/02/11(金) 23:45:01.94ID:MSfgatap
俺が入れ物に対して所有権があると>>900で書いたのも実質その型のインスタンスだ
インスタンスという言葉を使うと面倒になりそうなので抽象的に型の入れ物とした
いずれにせよ所有権の対象は値ではなく値が収容される入れ物orインスタンスだ

971デフォルトの名無しさん2022/02/11(金) 23:45:21.67ID:rRV0mw3H
実際のところ「値」と「インスタンス」の間にそんなに意味の差はないです。
特的の型を元に作られたということを強調するときにインスタンスと言うことはありますが、
どの値も型を持つのでインスタンスではない値などありはしません。

972デフォルトの名無しさん2022/02/11(金) 23:47:31.44ID:6Qn4bKwU
>>971
インスタンスはその型の形をした器(うつわ)であり解放されるまで不変
値はその器(うつわ)に入った内容にすぎず可変

973デフォルトの名無しさん2022/02/11(金) 23:48:11.08ID:rRV0mw3H
>>972
いいえ。 繰り返しますがそんな定義はないです。

974デフォルトの名無しさん2022/02/11(金) 23:49:47.15ID:3qua/k5E
>>967
>所有権を持っているのはあくまで値。

で、その値は何の所有権を持ってるのさ?

9759642022/02/11(金) 23:51:18.52ID:jgApYu5Z
そもそも「所有権を持つ」ってのが苦しい
英訳すると "own the ownership" になってしまうが、そんな表現は公式ドキュメントでも避けられてるように思う

値が変数に束縛されるとき、その値を変数が所有することになる
変数をreturnしたり、変数を他の変数に代入するときには、所有権がtransferされることになる

ここまでは良いでしょ
例えば、公式ドキュメントにもこう書かれてる
https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html
> Returning values can also transfer ownership.

なので、強いて >>961 の中から選ぶなら変数が所有権を持つだけど、最初に書いたようにそもそも「所有権を持つ」が苦しいので、
「変数が値を所有する」とすれば良いと思う

976デフォルトの名無しさん2022/02/11(金) 23:51:21.22ID:3qua/k5E
>>965
>「変数が値を所有する」

これが正解。

977デフォルトの名無しさん2022/02/11(金) 23:51:57.38ID:MSfgatap
>>973
皆がその点については定義がはっきりしないからこれだけ揉めてるんだろ
「そんな定義はないです」は反論にすらなっていない

9789642022/02/11(金) 23:53:29.17ID:jgApYu5Z
ああ、別に「持つ」を必ずしも "own" で訳す必要もないね
さっきから変なことばかり書いててすまんね、今日は冷静になっていったんもう寝る

979デフォルトの名無しさん2022/02/11(金) 23:54:02.65ID:rRV0mw3H
>>974
値自身を後始末する責任をもってる。
所有権という訳語がよくないというのはよく指摘されることだが、
何者かが値を所有しているという誤解のもとになるからだ。

変数が所有権を持っていることにしたら
一時オブジェクトの所有権はどうなってんだって話になるだろ。

980デフォルトの名無しさん2022/02/11(金) 23:57:48.33ID:6Qn4bKwU
>>975 >>976
そんな話は誰もしていないと思う
所有権は何に対して付随するのか生じているのかが論点
そして所有権が消滅するのは型のインスタンスが最後に解放される時
だから所有権と1対1の関係にあるのは(型の)インスタンスだと主張しています

981デフォルトの名無しさん2022/02/12(土) 00:03:26.33ID:mURtvSsP
>>972
> インスタンスはその型の形をした器(うつわ)であり解放されるまで不変

いいえ。
代入で内容が書き換えられる場合もあり、
そのときに drop が呼ばれます。
寿命の管理は値に付随します。

982デフォルトの名無しさん2022/02/12(土) 00:19:59.58ID:kNBFVDwU
とりあえずbookの
4.1. What is ownership?
https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html
からOwnership Rulesの節を丸ごと抜いてきた(訳は適当)


Ownership Rules

First, let’s take a look at the ownership rules.
Keep these rules in mind as we work through the examples that illustrate them:

* Each value in Rust has a variable that’s called its owner.
* There can only be one owner at a time.
* When the owner goes out of scope, the value will be dropped.


まずは所有権(ownership)に関するルールを見てみよう
このルールを記憶に留めて以下の例示を読み進めてほしい

・Rustの各々の値(value)は所有者(owner)と呼ばれる1つの変数(variable)をもつ
・所有者は同時に1つしか存在しない
・その所有者がスコープからいなくなる時、その値は破棄される

983デフォルトの名無しさん2022/02/12(土) 00:26:03.97ID:lHDa3hl7
>>982
これが正解

984デフォルトの名無しさん2022/02/12(土) 00:26:42.42ID:/iL1/Dd6
>>981
内容が書き換えられてdropすることはない
所有権と値は関係ない
値に付随するものではない

>>982に明記されているように所有権を持つ所有者は変数
所有者である変数がスコープから外れるとdrop

985デフォルトの名無しさん2022/02/12(土) 00:31:23.69ID:FSqSWy2H
>>982
だよなぁ。「入れ物」とか妙ちきりんな説明する人はなんなんだろう?

986デフォルトの名無しさん2022/02/12(土) 00:37:10.88ID:/iL1/Dd6
インスタンスというのも一理ある
その型のインスタンスが作られてから解放されるまで一貫して一つの存在なのに対して
変数は次々と移り変わって行く乗り物と捉えることができる
そしてインスタンスがたまたま束縛されている変数がスコープから消えると乗っていたインスタンスも巻き添えで消えると考えられないこともない

987デフォルトの名無しさん2022/02/12(土) 01:06:37.82ID:Q5zckJeE
>>980
スレ立てヨロ

988デフォルトの名無しさん2022/02/12(土) 01:26:58.40ID:aHobc4uM

989デフォルトの名無しさん2022/02/12(土) 01:32:16.48ID:/iL1/Dd6
>>988
GJ

990デフォルトの名無しさん2022/02/12(土) 01:58:18.50ID:eWE5dZha
横からすまんが、実際のメモリ上だと所有権ってどうなってるもんなの?
>>982にある仕組みからしたら・・・・メモリが確保されるのと同時に、併せて所有権情報(スタックへの参照か何か?)がメモリのどっか確保されるわけ?
俺、てっきりコンパイラへのただの指示だとばっか思ってたぜ

991デフォルトの名無しさん2022/02/12(土) 02:19:56.25ID:dWh4TlR2
横からキターーー

コンパイラの課すルールの話なので
所有権情報が実行時にメモリに確保されたりしないよ

992デフォルトの名無しさん2022/02/12(土) 04:01:34.21ID:tNCVqmWf
まじか、そうなんだ

993デフォルトの名無しさん2022/02/12(土) 06:46:04.75ID:zeKxBusw
ワッチョイ無しか、次スレも荒れそう

994デフォルトの名無しさん2022/02/12(土) 07:47:32.16ID:XghCcbPA
struct S;
impl Drop for S {
fn drop(&mut self) {
println!("drop");
}
}
fn main() {
S;
}
↑じゃあこれは何が所有権をもってて何がdropさせてんの?
インスタンス説のほうがまだシックリくる?
変数も所有権を持てるしスコープ終了で手放せる?

995デフォルトの名無しさん2022/02/12(土) 08:42:47.12ID:4ZF6L5uh
>>961
お前が突っかかって来たんだろうが
ガイジwwww

996デフォルトの名無しさん2022/02/12(土) 08:42:55.77ID:4ZF6L5uh
うんこ

997デフォルトの名無しさん2022/02/12(土) 08:43:01.75ID:4ZF6L5uh
まんげ

998デフォルトの名無しさん2022/02/12(土) 08:43:06.69ID:4ZF6L5uh
ちんげ

999デフォルトの名無しさん2022/02/12(土) 08:43:39.79ID:4ZF6L5uh
>>957
お前の負けやでwwwwwwww

1000デフォルトの名無しさん2022/02/12(土) 08:44:18.55ID:4ZF6L5uh
無教養のガイジども阿鼻叫喚していて草wっwr
ンゴwwwwwww


lud20220923011912ca
このスレへの固定リンク: http://5chb.net/r/tech/1636247099/
ヒント:5chスレのurlに http://xxxx.5chb.net/xxxx のようにbを入れるだけでここでスレ保存、閲覧できます。

TOPへ TOPへ  

このエントリをはてなブックマークに追加現在登録者数177 ブックマークへ


全掲示板一覧 この掲示板へ 人気スレ | Youtube 動画 >50 >100 >200 >300 >500 >1000枚 新着画像

 ↓「Rust part13 YouTube動画>2本 ->画像>1枚 」を見た人も見ています:
Naru Sato
Rust vs Go
Rust part9
Rust part8
SUPER GT+
PUSHIM Part1
Rust part14
Rust part15
Rust Part6
Rust Part5
Rust Part7
Rust part10
C++ vs Rust
Rust part12
Rust part6
Rust part11
Porteus Linux
Nexus 5X Part30
Castle Burn
OnePlus Part96
OnePlus Part87
OnePlus Part79
JUSWANNA Part.3
OnePlus Part81
Nexus 5X Part26
OnePlus Part94
Oneplus Part.4
Oneplus Part.5
Nexus 5 Part106
OnePlus Part46
Nexus 6 Part34
OnePlus Part20
Duelyst Part6
OnePlus Part91
OnePlus Part95
mist survival
OnePlus Part29
OnePlus Part77
OnePlus Part34
OnePlus Part22
ZOZOUSED part1
BEAT CRUSADERS 79
IPLE HOUSE Part5
OnePlus Part72
A-Studio Part4
Rustアンチスレ
OnePlus Part57
Android Studio 2
OnePlus Part10
iPhone6Plus Part4
Infected Mushroom
Russkij Avanpost
DE DE MOUSE☆Part3
Lost Frequencies
BURST in パンク板
STU48専用 うたコン
Change Request.
CRUSTスレ Part.13
乃木坂46専用 MUSIC FAIR
Houston Rockets 68
trap houseってなに?
Houston Rockets 67
the HIATUS Part 60
01:45:07 up 22 days, 2:48, 0 users, load average: 8.52, 11.65, 14.00

in 0.063818216323853 sec @0.063818216323853@0b7 on 020415