Closed4

Rustの所有権についてまとめる

あるべるとあるべると

まずは基本的な所

let s1 = String::from("hello");
let s2 = s1;

println!("{}, world!", s1);

※ 動かない

としたときRustではshallow copyすらされずにムーブが起きる
他の言語だとヒープに存在する実態とスタックに存在するポインタやlength、capacityがコピーされる(shallow copy)

let s1 = String::from("hello");
let s2 = s1.clone();

println!("s1 = {}, s2 = {}", s1, s2);

とすればヒープ上のデータもコピーされる(deep copy)

let x = 5;
let y = x;

println!("x = {}, y = {}", x, y);

は動く。整数などのスタック上に保持される値に関してはshallow copyしか起こり得ないので暗黙的なコピーが認められている。

  • 整数
  • 浮動小数
  • bool
  • 上記のみの型で構成されるタプル (i32, i32)はCopy、(i32, String)は違う

は暗黙的にコピーされる

あるべるとあるべると
fn main() {
    let s = String::from("hello");  // sがスコープに入る
    takes_ownership(s);             // sの値が関数にムーブされる
                                    // ... ここではもう有効ではない
}

fn takes_ownership(some_string: String) { // some_stringがスコープに入る。
    println!("{}", some_string);
} // ここでsome_stringがスコープを抜け、`drop`が呼ばれる。メモリが解放される。

関数に渡す際もmoveが発生する。なのでtakes_ownership関数の後にsを利用しようとするとコンパイルエラーになる。

値を返せば解決出来る。

fn main() {
    let s1 = String::from("hello");
    let s2 = takes_and_gives_back(s1);  // s1はtakes_and_gives_backにムーブされ
                                        // 戻り値もs2にムーブされる
}

fn takes_and_gives_back(a_string: String) -> String { // a_stringがスコープに入る。
    a_string  // a_stringが返され、呼び出し元関数にムーブされる
}

ただし、毎回返していては大変なので参照を利用する手もある。

fn main() {
    let s1 = String::from("hello");
    let len = calculate_length(&s1);
    println!("The length of '{}' is {}.", s1, len);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}
あるべるとあるべると
fn main() {
    let s = String::from("hello");
    change(&s);
}

fn change(some_string: &String) {
    some_string.push_str(", world");
}

rustにおいて単純な参照は不変なので上記のコードは動かない。
可変にしたければmutを付ける。

fn main() {
    let mut s = String::from("hello");

    change(&mut s);
}

fn change(some_string: &mut String) {
    some_string.push_str(", world");
}
あるべるとあるべると
fn main() {
    let reference_to_nothing = dangle();
}

fn dangle() -> &String {
    let s = String::from("hello");

    &s
}

変数のスコープを超えて参照は返せない。これはコンパイルエラーになる。
このあたりはライフタイムも絡むので別途まとめる

このスクラップは2024/12/29にクローズされました