Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Clone and Copy

리소스를 다룰 때, 기본 동작은 할당이나 함수 호출 시 리소스를 이전(transfer)하는 것입니다. 하지만 때로는 리소스의 복사본을 만들어야 할 때도 있습니다.

Clone 트레이트는 바로 이런 일을 돕습니다. 가장 일반적으로, Clone 트레이트에 정의된 .clone() 메서드를 사용할 수 있습니다.

Copy: Implicit Cloning

The Copy trait allows a type to be duplicated simply by copying bits, with no additional logic required. When a type implements Copy, assignments and function calls will implicitly copy the value instead of moving it.

Important: Copy requires Clone - any type that implements Copy must also implement Clone. This is because Copy is defined as a subtrait: trait Copy: Clone {}. The Clone implementation for Copy types simply copies the bits.

Not all types can implement Copy. A type can only be Copy if:

  • All of its components are Copy
  • It doesn’t manage external resources (like heap memory, file handles, etc.)
// A unit struct without resources
// Note: Copy requires Clone, so we must derive both
#[derive(Debug, Clone, Copy)]
struct Unit;

// A tuple struct with resources that implements the `Clone` trait
// This CANNOT be Copy because Box<T> is not Copy
#[derive(Clone, Debug)]
struct Pair(Box<i32>, Box<i32>);

fn main() {
    // `Unit`을 인스턴스화합니다
    let unit = Unit;
    // Copy `Unit` - this is an implicit copy, not a move!
    // Because Unit implements Copy, the value is duplicated automatically
    let copied_unit = unit;

    // 두 `Unit` 모두 독립적으로 사용될 수 있습니다.
    println!("원본: {:?}", unit);
    println!("복사본: {:?}", copied_unit);

    // `Pair`를 인스턴스화합니다
    let pair = Pair(Box::new(1), Box::new(2));
    println!("원본: {:?}", pair);

    // Move `pair` into `moved_pair`, moves resources
    // Pair does not implement Copy, so this is a move
    let moved_pair = pair;
    println!("이동됨: {:?}", moved_pair);

    // 에러! `pair`는 리소스를 잃었습니다
    //println!("original: {:?}", pair);
    // TODO ^ 이 줄의 주석을 해제해 보세요

    // Clone `moved_pair` into `cloned_pair` (resources are included)
    // Unlike Copy, Clone is explicit - we must call .clone()
    let cloned_pair = moved_pair.clone();
    // `std::mem::drop`을 사용하여 이동된 원본 페어를 해제합니다
    drop(moved_pair);

    // 에러! `moved_pair`가 해제되었습니다
    //println!("moved and dropped: {:?}", moved_pair);
    // TODO ^ 이 줄의 주석을 해제해 보세요

    // `.clone()`의 결과는 여전히 사용될 수 있습니다!
    println!("클론: {:?}", cloned_pair);
}