目次
前回の記事はこちら。自分用のメモなので、読みにくいかもです。
第4章
第4章です。たぶん、これがいちばん大事な概念だと思います、Rustの。 そして、つまみ食いしながらRust書いてましたが、ここがきちんと理解できないまま書いてたってのもあります。。。
所有権とは?
drop
関数ってのがあって、明示的に呼ぶことも可能。次のような感じで。2つ目のprintln!
はエラーになる。sがもう無いのに借用しようとしてるから。
fn main() {
let mut s = String::from("hello");
s.push_str(", world!");
println!("{}", s);
drop(s);
println!("{}", s);
}
- ムーブ - shallow copyではない。以下の2行目がムーブ。
let s1 = String::from("hello");
let s2 = s1;
println!("{}, world!", s1);
スタックとヒープの話が絡んでくる。あんまり意識すること無いよなぁ。 スタック = 固定長のデータを入れる場所。ポインタ、数値など ヒープ = 可変長のデータが入る場所。可変の文字列とか。
- クローン - ヒープのデータをコピーすること。
- コピー - スタックに収まるデータの場合はクローンが必要なくコピーで事足りる。
- CopyトレイととDropトレイとは同居できない。
- タプルのコピーはややこしそう
- 所有権と関数でまた、スタックに入れられるような変数と可変のオブジェクトの違いが出てくる。
takes_ownership(s: String)
が参照を受け取れば問題なく、このあとも使える。- 戻り値でもムーブが発生
参照と借用
- 借用 - 関数の引数に参照を取ること
- 可変な参照
&mut
は1つ(不変な参照も含めて1つ)しか許さない- データの競合を防ぐため。
- 不変な参照を複数用いるのはOK
- 実際に変更が実行されるタイミングでエラーと判定される場合もある。
let mut s = String::from("hello");
{
let r1 = &mut s;
} // r1はここでスコープを抜けるので、問題なく新しい参照を作ることができる
let r2 = &mut s;
- ダングリング参照はテスト書くときとかにやってるかも。。。
fn dangle() -> &String { // dangleはStringへの参照を返す
let s = String::from("hello"); // sは新しいString
&s // String sへの参照を返す
} // ここで、sはスコープを抜け、ドロップされる。そのメモリは消される。
// 危険だ
スライス型
- 部分的な参照。開始位置+長さで構成されているっぽい
&str
の説明がよくわからなかった。
引数としての文字列スライスのテクニックは色々と使いまわせそう。
まとめ
所有権、これまで特に難しいと思ってたのは、固定長の変数と、可変長の変数の違いを意識してなかったのが原因っぽい。 まぁ、Vecとかがどうなるのかとか、他にもいくつか気になるところはあるので、もうちょっとやらないといけないなと思いました。
comments powered by Disqus
See Also by Hugo
- Rust the book - 第8章
- Rust the book - 第10章
- Rust the book - 第9章
- Rust the book - 第6章
- Rust the book - 第5章