복사와 복제의 차이점은 무엇입니까?


답변:


115

Clone임의의 중복을 위해 설계되었습니다 Clone. 유형에 대한 구현 T은 새 파일을 만드는 데 필요한 임의의 복잡한 작업을 수행 할 수 있습니다T . 이것은 일반적인 특성 (전주곡에있는 것 제외)이므로 일반적인 특성처럼 메서드 호출 등으로 사용되어야합니다.

Copy특성은 안전하게 통해 중복 될 수있는 값 대표 memcpy: 재 할당 항상 함수에 의해 값 인수를하는 통과 같은 것들을 memcpy들, 등등에 대한 Copy유형, 컴파일러가 그 고려할 필요가 없다는 것을 이해하고 이동 .


5
Clone딥 카피와 Copy섀도우 카피를 이해할 수 있습니까 ?
Djvu

11
Clone유형이 딥 또는 얕은 복사를 수행 할 가능성 을 엽니 다 : "임의로 복잡함".
poolie

85

주요 차이점은 복제가 명시 적이라는 것입니다. 암시 적 표기법은 Copy유형 이 아닌 이동을 의미 합니다.

// u8 implements Copy
let x: u8 = 123;
let y = x;
// x can still be used
println!("x={}, y={}", x, y);

// Vec<u8> implements Clone, but not Copy
let v: Vec<u8> = vec![1, 2, 3];
let w = v.clone();
//let w = v // This would *move* the value, rendering v unusable.

그런데 모든 Copy유형도 Clone. 그러나 동일한 작업을 수행 할 필요는 없습니다! 자신의 유형에 .clone()대해는 원하는 임의의 방법이 될 수 있지만 암시 적 복사는 항상 구현이 memcpy아닌을 트리거합니다 clone(&self).


1
멋있는! 이것은 클론 특성이 암시 적 복사를 제공하는지 여부에 관한 두 번째 질문을 해결합니다. 그 질문과이 질문은 제가 생각했던 것보다 더 관련이 있습니다. 감사!
user12341234 2015-06-23

첫 번째 예에서 마지막으로 주석 처리 한 예와 같이 사본이 아닌 y이동 을 원한다고 가정합니다 . 어떻게 지정 하시겠습니까? xw = v
johnbakers

2
당신은 할 수없고 그렇지 않습니다. Copy왜냐하면는 u8예제에서 와 같이 "저렴한"유형을 위해 구현 되기 위한 것이기 때문 입니다 . 이동이 복사보다 효율적이라고 생각하는 상당히 무거운 유형을 작성하는 경우 impl을 사용 하지 마십시오Copy . u8의 경우, 이동으로 더 효율적일 수는 없습니다. 후드 아래에서 적어도 포인터 복사를 수반 할 것이기 때문입니다. 이미 u8 복사만큼 비용이 많이 들기 때문에 왜 귀찮습니다.
mdup

이것은 Copy특성 의 존재 가 변수의 암묵적 수명 범위에 영향을 미친다는 것을 의미합니까 ? 그렇다면 주목할 만하다고 생각합니다.
Brian Cain

7

이미 다른 답변에서 다루었 듯이 :

  • Copy 암시 적이며 저렴하며 다시 구현할 수 없습니다 (memcpy).
  • Clone 명시 적이며 비용이 많이 들고 임의로 다시 구현할 수 있습니다.

Copyvs 논의에서 때때로 누락 된 Clone것은 컴파일러가 이동과 자동 복사를 사용하는 방식에도 영향을 미친다는 것입니다. 예를 들면 :

#[derive(Debug, Clone, Copy)]
pub struct PointCloneAndCopy {
    pub x: f64,
}

#[derive(Debug, Clone)]
pub struct PointCloneOnly {
    pub x: f64,
}

fn test_copy_and_clone() {
    let p1 = PointCloneAndCopy { x: 0. };
    let p2 = p1; // because type has `Copy`, it gets copied automatically.
    println!("{:?} {:?}", p1, p2);
}

fn test_clone_only() {
    let p1 = PointCloneOnly { x: 0. };
    let p2 = p1; // because type has no `Copy`, this is a move instead.
    println!("{:?} {:?}", p1, p2);
}

첫 번째 예제 ( PointCloneAndCopy)는 암시 적 복사 때문에 여기에서 잘 작동하지만 두 번째 예제 ( PointCloneOnly)는 이동 후 사용시 오류가 발생합니다.

error[E0382]: borrow of moved value: `p1`
  --> src/lib.rs:20:27
   |
18 |     let p1 = PointCloneOnly { x: 0. };
   |         -- move occurs because `p1` has type `PointCloneOnly`, which does not implement the `Copy` trait
19 |     let p2 = p1;
   |              -- value moved here
20 |     println!("{:?} {:?}", p1, p2);
   |                           ^^ value borrowed here after move

암시 적 이동을 피하기 위해 명시 적으로 let p2 = p1.clone();.

이것은 Copy 특성을 구현하는 유형의 이동을 강제하는 방법에 대한 질문을 제기 할 수 있습니까? . 짧은 대답 : 말이 안 돼요 / 말이 안 돼요.


@Shepmaster Rust 컴파일러의 멋진 색상 코딩이 포함되어 있기 때문에 훨씬 더 읽기 쉬워졌지만 제거했으며 모든 검색 관련 단어도 텍스트에 포함되어 있는지 확인했습니다.
bluenote10
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.