let b = a;←bに所有権が移動(プリミティヴじゃない型なら普通ここでaは破棄される)
test(a);←test()関数を作りaを渡す
test1(a);
test2(a);
↑
これ普通にうごくんだがwwww
let a = String::from("VIP");←プリミティヴじゃない型の代表としてString型とする
let b = a;
test(a);←これでコンパイルエラー
あとからどんどんいらない機能足していってカオスになりそうな未来しか無い
文字列ってのは型じゃなくて配列なんだよ
その最初の基本を知らんから同じように型だと思っちゃう
いやだとしてもi32が移動されないのは問題だろ
シーシャはさぁ流行りのIT用語に惑わされすぎ
本当に情報工学やりたいならちゃんとC言語とアセンブラやってメモリとアドレスの勉強しなさい
情熱が空回りしてますよ
Copyトレイトでググれ
なぜプリミティヴ型の場合は安全になるの?
教えてくれ
&つけるやつ?
それ参照渡しだろ?
これは参照渡しじゃない
どう見てもダブスタでは?
プリミティブ型が安全などという概念自体がない
シーシャはどうして誰も言ってないことをいきなり言い出すのか
2. コピーはできるがコストのかかる型 (動的配列や文字列などヒープを使うもの)
3. コピーにコストのかからない型 (整数型など)
とあって、2はCloneトレイトを、3はCloneとCopyトレイトで表現される
正しくは「Copyトレイトを実装した型は暗黙的にコピーされる」「Cloneのみの型は .clone() を明示的に呼ぶ必要がある」といった感じ
整数はもちろんCopyを実装してるのでコピーできるけど、コピーのコストが小さいものは自作型でもCopyにできるし、プリミティブ型だけを特別扱いしてるわけではない
安全だからコンパイルできるようになってんじゃねぇの?
コピーしたメモリを渡してるってこと?
この
let b = a;は
といえば分かるかもしれない
つまりRust勉強する前にC++勉強しろってこと?
なら誰もRustなんか習得しないと思うけど
ブロック抜けるまで破棄されない感じになんのか?
それはメモリコピーしたbも同様ってことか?
bとaは別のメモリアドレスで、(Copyなら) 格納されてる値がbからaにコピーされる
メモリ上の表現をそのままコピーすると思っても問題ない
文字列型であれば、aはポインタみたいなもので、aは更に別の領域に確保された文字列を指している
let b = a.clone() は、aとは別の領域に文字列を確保して、aが指す領域にある文字列をコピーし、その参照をbに代入する
もちろん文字列が長くなればなるほどコピーするデータ量が増えるので、これは整数型をコピーするのとは違いコストがかかる
だから文字列や配列などはCopyではなくCloneになってて、コピーする際に明示的に clone を呼ぶ必要があるようにしてる
型の破棄とかいうわけのわからないことを言い出すんだ、そんなもんないわ
シーシャはもうプログラミング用語を勝手に自分で解釈するくせやめろ
GO言語のほうがお前には向いてるよ
ブロックを抜けたときと思ってOK
整数の場合はスタックにあるものなので、解放時に特別な処理が走ったりはしない
文字列や配列かつそのデータを他と共有していない場合 (RcやArcを使ってない場合) は、ブロックを抜けたタイミングでヒープのデータも解放される
なるほど
let b = a.clone() は、aとは別の領域に文字列を確保して、aが指す領域にある文字列をコピーし、その参照をbに代入する
もちろん文字列が長くなればなるほどコピーするデータ量が増えるので、これは整数型をコピーするのとは違いコストがかかる
で何言ってんだこいつ?って思ったけどa. cloneはイメージ的にaのCopyみたいな感覚か
let a = String::from("hage");
let b = a;
はクローンでもない単純にメモリアドレスを渡してるという事か
いや俺はC#するよ
Google嫌いなのでGoは一生使いません
型の解放なんか一つも言ってねぇよ
メモリの解放って意味なんだが
文字列とかの場合
{
let b = String::from("Hage");
test(b);
}
の場合このブロックが終了してもbは保持されててtest()が終わった段階で破棄されるってことか
文字列は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 される
let b = a.cloneはメモリコピーで
let b = aはアドレスを渡してるってことだよね?
でletb = aの時のメモリはbが破棄されたタイミングで破棄されるということ(ブロックでは破棄されない)
Rust学ぶ気が無いゴミがなんか言ってるw
イメージでRust持ち上げててワロタwww
正直そうなればRustの存在価値とか無くなる
公式チュートリアルすら読まないやつがなんか言ってるw
aが指す領域のアドレスをbに渡し、かつ a をそれ以降使えなくしてる
それがいわゆるムーブ
let a = … で確保された領域を、cloneのように追加のメモリ確保なしにbに渡してる
この文字列領域の所有権はbに移ったので、この操作のあとはaは使えない
aの方もまだ使うなら let b= &a にする
bにコピーしたあとaの内容を変更するつもりなら a.clone() する
といった使い分け
実体を持っている変数は代入で実体コピー、ポインタを持っている変数は代入でポインタコピーされる
この動作は一貫性があるけど「ys=xsでコピーしたと思ったらしてなかった」ありがちな間違いを起こしやすい
だからその間違いをコンパイルエラーにしてやろうってのが面白いしプリミティブな型と違うのもすんなり納得できる
なるほどサンクス
だがダブスタなのは間違いない
そもそもcopyを実装してるという認識が無ければ誰でも間違いが起こりうる
上に言ってるとおりCを勉強してればという前提条件がある時点でダブスタクソ言語であることは確定
スクール行ったとしてCわかる教師じゃないと説明できないだろこれ
今のなんちゃってスクールにわかるやつどんだけいんだって話
こういった型でも必ず clone() が必要だったり、変数が使えなくなったりしても面倒なので let b = a; で簡単にコピーできるようになってる
Copyを実装する型は基本的に同様
内部のメモリ管理とか知らんしどうでもいい😡それより外側からの見た目が均一になるようにしろ
みたいにpythonとかの超高級言語派が思うのはすごくわかる
実際それのほうが簡単で仕事でも採用しやすいから人気が高いし
一方で難しくて使いにくいc,c++が未だに生き残ってるのはそういう難しいことを意識しないといけない領域があるからなんだよね
rustはc++言語の領域を代替するために生まれた言語だから超高級言語から来た人からすれば「こんな複雑さいらないだろ😡」って怒るわけだ
結局、多分お前はrustに期待しすぎていたのかな?今まで使っていた言語とまったく同じでかつパフォーマンスが最高であってくれっていう期待を打ち砕かれてブチギレてるわけだ
いや普通にC#にLLVMがくるならそれ使うよねって話
かつ C++ と違ってムーブが基本だから「気付かないうちにコストの重いコピーが走る」がないのが良いよね
C++のstd::vectorは=演算子でディープコピーになる (ムーブするのに明示的な std::move が要る) けど
Rustは逆にムーブが基本で clone() の方に明示が必要という言語
The post 【プログラミング】Rust勉強し始めたけどダブスタが多すぎる first appeared on あらまめ2ch.
Copyright © 2024 あらまめ2ch All Rights Reserved.