【RSS】PCメイン記事上ワイド1

【プログラミング】Rust勉強し始めたけどダブスタが多すぎる





1: 2024/09/20(金) 21:45:50.325 ID:kWqZd/zt0.net
プリミティヴ型は所有権が移動しても破棄されないとかダブスタにも程があるんよ



2: 2024/09/20(金) 21:48:44.541 ID:kWqZd/zt0.net
let a = 5;←プリミティヴ型のint i32
let b = a;←bに所有権が移動(プリミティヴじゃない型なら普通ここでaは破棄される)
test(a);←test()関数を作りaを渡す
test1(a);
test2(a);

これ普通にうごくんだがwwww



3: 2024/09/20(金) 21:50:28.092 ID:kWqZd/zt0.net
逆に
let a = String::from("VIP");←プリミティヴじゃない型の代表としてString型とする
let b = a;
test(a);←これでコンパイルエラー



4: 2024/09/20(金) 21:51:51.368 ID:kWqZd/zt0.net
こういうダブスタの多い言語って全然完成されてる感無いから嫌いなんだが
あとからどんどんいらない機能足していってカオスになりそうな未来しか無い



5: 2024/09/20(金) 21:54:34.166 ID:VgAEOlzo0.net
先にC言語やりなって・・・
文字列ってのは型じゃなくて配列なんだよ
その最初の基本を知らんから同じように型だと思っちゃう



6: 2024/09/20(金) 21:58:31.550 ID:kWqZd/zt0.net
>>5
いやだとしてもi32が移動されないのは問題だろ



7: 2024/09/20(金) 22:00:39.856 ID:VgAEOlzo0.net
そんな風に思っちゃうのはメモリ内部のアドレスがどうなってるか全然予想できてないからに過ぎない
シーシャはさぁ流行りのIT用語に惑わされすぎ
本当に情報工学やりたいならちゃんとC言語とアセンブラやってメモリとアドレスの勉強しなさい
情熱が空回りしてますよ



8: 2024/09/20(金) 22:08:27.801 ID:9Rx1thwJ0.net
プリミティブかどうかは関係ないぞ
Copyトレイトでググれ



9: 2024/09/20(金) 22:09:57.110 ID:kWqZd/zt0.net
>>7
なぜプリミティヴ型の場合は安全になるの?
教えてくれ



10: 2024/09/20(金) 22:10:47.696 ID:kWqZd/zt0.net
>>8
&つけるやつ?
それ参照渡しだろ?
これは参照渡しじゃない





11: 2024/09/20(金) 22:11:52.949 ID:kWqZd/zt0.net
これをダブスタと言えない理由を教えてくれよ
どう見てもダブスタでは?



12: 2024/09/20(金) 22:13:03.921 ID:VgAEOlzo0.net
>>9
プリミティブ型が安全などという概念自体がない
シーシャはどうして誰も言ってないことをいきなり言い出すのか



13: 2024/09/20(金) 22:14:28.541 ID:9Rx1thwJ0.net
1. コピーしてはならない型 (ファイルハンドルなど)
2. コピーはできるがコストのかかる型 (動的配列や文字列などヒープを使うもの)
3. コピーにコストのかからない型 (整数型など)

とあって、2はCloneトレイトを、3はCloneとCopyトレイトで表現される
正しくは「Copyトレイトを実装した型は暗黙的にコピーされる」「Cloneのみの型は .clone() を明示的に呼ぶ必要がある」といった感じ

整数はもちろんCopyを実装してるのでコピーできるけど、コピーのコストが小さいものは自作型でもCopyにできるし、プリミティブ型だけを特別扱いしてるわけではない



14: 2024/09/20(金) 22:15:54.496 ID:kWqZd/zt0.net
>>12
安全だからコンパイルできるようになってんじゃねぇの?



15: 2024/09/20(金) 22:17:19.359 ID:kWqZd/zt0.net
>>13
コピーしたメモリを渡してるってこと?
この
let b = a;は



16: 2024/09/20(金) 22:17:54.275 ID:9Rx1thwJ0.net
もしC++の経験があるなら、std::vectorやstd::stringのようなものはCloneのみで、std::string_viewやstd::spanみたいなものはCopyにする、
といえば分かるかもしれない



17: 2024/09/20(金) 22:20:06.236 ID:kWqZd/zt0.net
>>16
つまりRust勉強する前にC++勉強しろってこと?
なら誰もRustなんか習得しないと思うけど



18: 2024/09/20(金) 22:21:30.574 ID:kWqZd/zt0.net
じゃあaが破棄されるタイミングっていつなんだ?
ブロック抜けるまで破棄されない感じになんのか?
それはメモリコピーしたbも同様ってことか?



19: 2024/09/20(金) 22:25:16.448 ID:9Rx1thwJ0.net
>>15
bとaは別のメモリアドレスで、(Copyなら) 格納されてる値がbからaにコピーされる
メモリ上の表現をそのままコピーすると思っても問題ない

文字列型であれば、aはポインタみたいなもので、aは更に別の領域に確保された文字列を指している
let b = a.clone() は、aとは別の領域に文字列を確保して、aが指す領域にある文字列をコピーし、その参照をbに代入する
もちろん文字列が長くなればなるほどコピーするデータ量が増えるので、これは整数型をコピーするのとは違いコストがかかる
だから文字列や配列などはCopyではなくCloneになってて、コピーする際に明示的に clone を呼ぶ必要があるようにしてる



20: 2024/09/20(金) 22:25:20.171 ID:VgAEOlzo0.net
プログラミングの基本であるヒープにおけるメモリ確保と解放を理解できてないから
型の破棄とかいうわけのわからないことを言い出すんだ、そんなもんないわ
シーシャはもうプログラミング用語を勝手に自分で解釈するくせやめろ






21: 2024/09/20(金) 22:27:04.829 ID:OzrU8wc70.net
c言語も知らないメモリ管理に興味ないならわざわざrustやる理由ないだろ
GO言語のほうがお前には向いてるよ



22: 2024/09/20(金) 22:29:49.180 ID:9Rx1thwJ0.net
>>18
ブロックを抜けたときと思ってOK
整数の場合はスタックにあるものなので、解放時に特別な処理が走ったりはしない
文字列や配列かつそのデータを他と共有していない場合 (RcやArcを使ってない場合) は、ブロックを抜けたタイミングでヒープのデータも解放される



23: 2024/09/20(金) 22:30:55.923 ID:kWqZd/zt0.net
>>19
なるほど
let b = a.clone() は、aとは別の領域に文字列を確保して、aが指す領域にある文字列をコピーし、その参照をbに代入する
もちろん文字列が長くなればなるほどコピーするデータ量が増えるので、これは整数型をコピーするのとは違いコストがかかる
で何言ってんだこいつ?って思ったけどa. cloneはイメージ的にaのCopyみたいな感覚か

let a = String::from("hage");
let b = a;
はクローンでもない単純にメモリアドレスを渡してるという事か



24: 2024/09/20(金) 22:31:28.655 ID:kWqZd/zt0.net
>>21
いや俺はC#するよ
Google嫌いなのでGoは一生使いません



25: 2024/09/20(金) 22:32:04.052 ID:kWqZd/zt0.net
>>20
型の解放なんか一つも言ってねぇよ
メモリの解放って意味なんだが



26: 2024/09/20(金) 22:35:02.815 ID:kWqZd/zt0.net
>>22
文字列とかの場合
{
let b = String::from("Hage");
test(b);
}
の場合このブロックが終了してもbは保持されててtest()が終わった段階で破棄されるってことか



29: 2024/09/20(金) 22:40:23.098 ID:9Rx1thwJ0.net
>>23
文字列はcloneしないとコンパイルエラー
let a = String::from("hage");
let b = a.clone();

これはC風にいえば
let a = … の箇所で文字列の長さだけmallocされて、そのポインタがaに代入される
let b = a.clone() の箇所は
・文字列と同じ長さだけmallocし、ポインタをbに代入する
・文字列の長さだけmemcpyして、aが指す文字列の内容をbが指す領域にコピーする
といった感じ
a や b が確保したメモリはスコープを抜けた際に free される



30: 2024/09/20(金) 22:44:34.155 ID:kWqZd/zt0.net
>>29
let b = a.cloneはメモリコピーで
let b = aはアドレスを渡してるってことだよね?
でletb = aの時のメモリはbが破棄されたタイミングで破棄されるということ(ブロックでは破棄されない)



31: 2024/09/20(金) 22:48:36.142 ID:j7WXiP890.net
一生c#に閉じこもってろ



32: 2024/09/20(金) 22:49:32.145 ID:kWqZd/zt0.net
>>31
Rust学ぶ気が無いゴミがなんか言ってるw
イメージでRust持ち上げててワロタwww






33: 2024/09/20(金) 22:53:03.877 ID:kWqZd/zt0.net
Rustの速さって制限かけてLLVMで機械語に翻訳出来るってところしかないんだから他のメモリ安全の言語でLLVMに通せたらそれが一番いいよねって話になる
正直そうなればRustの存在価値とか無くなる



34: 2024/09/20(金) 22:54:24.290 ID:j7WXiP890.net
公式チュートリアルも読めない奴がなんか言ってる



35: 2024/09/20(金) 22:55:15.654 ID:kWqZd/zt0.net
>>34
公式チュートリアルすら読まないやつがなんか言ってるw



36: 2024/09/20(金) 22:57:28.077 ID:9Rx1thwJ0.net
>let b = aはアドレスを渡してるってことだよね?
aが指す領域のアドレスをbに渡し、かつ a をそれ以降使えなくしてる
それがいわゆるムーブ
let a = … で確保された領域を、cloneのように追加のメモリ確保なしにbに渡してる
この文字列領域の所有権はbに移ったので、この操作のあとはaは使えない

aの方もまだ使うなら let b= &a にする
bにコピーしたあとaの内容を変更するつもりなら a.clone() する
といった使い分け



37: 2024/09/20(金) 22:57:29.311 ID:OzrU8wc70.net
c言語(というか低レベルなメモリ管理)が配列をどんなふうに扱ってるか知れば一貫性があるし混乱しにくくて面白い仕様だと思えるんだけどね
実体を持っている変数は代入で実体コピー、ポインタを持っている変数は代入でポインタコピーされる
この動作は一貫性があるけど「ys=xsでコピーしたと思ったらしてなかった」ありがちな間違いを起こしやすい
だからその間違いをコンパイルエラーにしてやろうってのが面白いしプリミティブな型と違うのもすんなり納得できる



38: 2024/09/20(金) 22:58:45.559 ID:kWqZd/zt0.net
>>36
なるほどサンクス



39: 2024/09/20(金) 22:58:55.247 ID:+/BJo4cO0.net
やっぱりスクール通ったほうが覚えが速いな



41: 2024/09/20(金) 23:01:20.679 ID:kWqZd/zt0.net
>>37
だがダブスタなのは間違いない
そもそもcopyを実装してるという認識が無ければ誰でも間違いが起こりうる
上に言ってるとおりCを勉強してればという前提条件がある時点でダブスタクソ言語であることは確定



43: 2024/09/20(金) 23:02:24.971 ID:kWqZd/zt0.net
>>39
スクール行ったとしてCわかる教師じゃないと説明できないだろこれ
今のなんちゃってスクールにわかるやつどんだけいんだって話



45: 2024/09/20(金) 23:06:03.425 ID:9Rx1thwJ0.net
最初の質問に補足すると、整数型は文字列のように「別の領域にデータを持つ」ものではないので、所有権の問題だとかコピーのコストとかが関係ない
こういった型でも必ず clone() が必要だったり、変数が使えなくなったりしても面倒なので let b = a; で簡単にコピーできるようになってる
Copyを実装する型は基本的に同様



[ad_fluct4][記事中固定リンク4]

51: 2024/09/20(金) 23:12:57.556 ID:tnbQxuCy0.net
>>41
内部のメモリ管理とか知らんしどうでもいい😡それより外側からの見た目が均一になるようにしろ
みたいにpythonとかの超高級言語派が思うのはすごくわかる
実際それのほうが簡単で仕事でも採用しやすいから人気が高いし
一方で難しくて使いにくいc,c++が未だに生き残ってるのはそういう難しいことを意識しないといけない領域があるからなんだよね
rustはc++言語の領域を代替するために生まれた言語だから超高級言語から来た人からすれば「こんな複雑さいらないだろ😡」って怒るわけだ
結局、多分お前はrustに期待しすぎていたのかな?今まで使っていた言語とまったく同じでかつパフォーマンスが最高であってくれっていう期待を打ち砕かれてブチギレてるわけだ



53: 2024/09/20(金) 23:14:02.080 ID:kWqZd/zt0.net
>>51
いや普通にC#にLLVMがくるならそれ使うよねって話



54: 2024/09/20(金) 23:16:12.238 ID:9Rx1thwJ0.net
>>37
かつ C++ と違ってムーブが基本だから「気付かないうちにコストの重いコピーが走る」がないのが良いよね
C++のstd::vectorは=演算子でディープコピーになる (ムーブするのに明示的な std::move が要る) けど
Rustは逆にムーブが基本で clone() の方に明示が必要という言語







関連記事