クローン

メモリ上の資源を扱う際、変数束縛や関数呼び出しを介して移動させるのがデフォルトの挙動です。しかしながら、場合によっては資源のコピーを作るのが適切なこともあります。

Cloneトレイトはまさにこのためにあります。普通はCloneトレイトで定義されている.clone()を用います。

// A unit struct without resources
// いかなる資源も持たない構造体
#[derive(Debug, Clone, Copy)]
struct Nil;

// A tuple struct with resources that implements the `Clone` trait
// `Clone`トレイトを実装する型の変数を資源として持つタプル
#[derive(Clone, Debug)]
struct Pair(Box<i32>, Box<i32>);

fn main() {
    // Instantiate `Nil`
    // `Nil`のインスタンスを作成
    let nil = Nil;
    // Copy `Nil`, there are no resources to move
    // `Nil`をコピー、移動させる資源は存在しない
    let copied_nil = nil;

    // Both `Nil`s can be used independently
    // いずれの`Nil`も独立に使用できる。
    println!("original: {:?}", nil);
    println!("copy: {:?}", copied_nil);

    // Instantiate `Pair`
    // `Pair`のインスタンスを作成
    let pair = Pair(Box::new(1), Box::new(2));
    println!("original: {:?}", pair);

    // Copy `pair` into `moved_pair`, moves resources
    // `pair`を`moved_pair`にコピー、資源は移動(`move`)する。
    let moved_pair = pair;
    println!("copy: {:?}", moved_pair);

    // Error! `pair` has lost its resources
    // エラー! `pair`は資源を失っている。
    //println!("original: {:?}", pair);
    // TODO ^ Try uncommenting this line
    // TODO ^ この行をアンコメントしてみましょう。
    
    // Clone `moved_pair` into `cloned_pair` (resources are included)
    // `moved_pair`を`cloned_pair`にクローンする。(資源もクローンされる。)
    let cloned_pair = moved_pair.clone();
    // Drop the original pair using std::mem::drop
    // std::mem::dropを用いて元のpairをドロップする
    drop(moved_pair);

    // Error! `moved_pair` has been dropped
    // エラー! `moved_pair`はドロップされている。
    //println!("copy: {:?}", moved_pair);
    // TODO ^ Try uncommenting this line
    // TODO ^ この行をアンコメントしてみましょう。

    // The result from .clone() can still be used!
    // .clone()した値はまだ使用可能!
    println!("clone: {:?}", cloned_pair);
}