CopyとClone(@Rust)

Rustの場合のCopyとCloneの例を見ると、

https://doc.rust-lang.org/std/marker/trait.Copy.html

のコードからlet y = xのように代入すると、

<これはmove>

#[derive(Debug)]
struct Foo;

let x = Foo;

let y = x;

// `x` has moved into `y`, and so cannot be used

// println!("{x:?}"); // error: use of moved value

したがって元のxにはアクセスできない。

 

<CopyをderiveすればCopy、ただしCloneもderiveしないとダメ>

“We can derive a `Copy` implementation. `Clone` is also required, as it’s

 a super trait of `Copy`.”

// We can derive a `Copy` implementation. `Clone` is also required, as it's
// a supertrait of `Copy`.
#[derive(Debug, Copy, Clone)]
struct Foo;

let x = Foo;

let y = x;

// `y` is a copy of `x`

println!("{x:?}"); // A-OK!

Cloneのドキュメントへのリンクは、

https://doc.rust-lang.org/std/clone/trait.Clone.html

さて、

https://doc.rust-jp.rs/rust-by-example-ja/trait/clone.html

のコードを再掲すると、

// A unit struct without resources
// Clone must also have to be derived when you use Copy
#[derive(Debug, Clone, Copy)]
struct Unit;

// A tuple struct with resources that implements the `Clone` trait
// Copy can not be applied to Pair struct
#[derive(Clone, Debug)]
struct Pair(Box, Box);

fn main() {
    // Instantiate `Unit`
    let unit = Unit;
    // Copy `Unit`, there are no resources to move
    let copied_unit = unit;

    // Both `Unit`s can be used independently
    println!("original: {:?}", unit);
    println!("copy: {:?}", copied_unit);


    // ----------- from here, Pair is handled -----------
    // Instantiate `Pair`
    let pair = Pair(Box::new(1), Box::new(2));
    println!("original: {:?}", pair);

    // Move `pair` into `moved_pair`, moves resources
    let moved_pair = pair;
    println!("moved: {:?}", moved_pair);

    // Error! `pair` has lost its resources
    //println!("original: {:?}", pair);
    // TODO ^ Try uncommenting this line

    // Clone `moved_pair` into `cloned_pair` (resources are included)
    let cloned_pair = moved_pair.clone();
    println!("cloned original: {:?}", moved_pair);
    // Drop the original pair using std::mem::drop
    drop(moved_pair);

    // Error! `moved_pair` has been dropped
    //println!("copy: {:?}", moved_pair);
    // TODO ^ Try uncommenting this line

    // The result from .clone() can still be used!
    println!("clone: {:?}", cloned_pair);
}

構造体の要素がプリミティブな型だとCopyが適用できるけれども、Box<i32>のような要素を持つとCopyは適用できない。

このソースを見ると、struct UnitにはCopyとCloneがderivesされていますがstruct Pair(Box, Box)にはCloneだけderiveコードを見るとCopyは暗黙(implicit)であり、Cloneはmoved_pair.clone()としているから明示的(explicit)であることがわかります。

 

admin

カテゴリーRust