질문의 역사:
Rust에서는 메모리 관리 및 소유권 개념이 객체가 어떻게 이동되고 복사되는지를 명확하게 정의해야 합니다. 언어가 시작될 때 바이트 복사(할당 및 논리 없이)와 깊은 복제(예: 문자열, 벡터 복사)를 구별하는 것이 중요했습니다. 이를 위해 두 가지 트레이트인 Copy와 Clone이 도입되었습니다.
문제는 모든 데이터 유형이 똑같이 저렴하게 복사되지 않는다는 것입니다. 일부 구조에서 복사는 단순히 비트 복사입니다(예: 정수 또는 Copy 유형의 튜플), 반면 다른 구조(예: String, Vec)에서는 메모리 할당과 같은 추가 작업이 필요합니다. Copy와 Clone의 분리는 Rust가 잘못된 복사를 시도할 때 컴파일 오류를 제공할 수 있게 합니다.
해결책:
Copy로 표시된 유형은 전달, 할당 및 함수에 전달 시 자동으로 복사됩니다. 이러한 유형의 객체는 복사 후에도 여전히 유효합니다.Clone을 구현하며, 이는 명시적으로 .clone() 메서드를 호출해야 하며, 종종 추가 자원 할당이 필요합니다.코드 예:
#[derive(Debug, Copy, Clone)] struct Point { x: i32, y: i32, } fn main() { let p1 = Point { x: 1, y: 2 }; let p2 = p1; // p1이 "무효"가 되지 않음 println!("{:?} {:?}", p1, p2); }
주요 특징:
Copy - 자동 비트 복사, 수동 호출이 필요 없으며 소유권에 영향을 미치지 않음.Clone - 명시적인 깊은 복사로, 힙 데이터를 포함한 구조에 적합.힙 할당된 데이터를 가진 유형이 Copy를 파생할 수 있을까요?
아니요, 힙 데이터를 포함한 유형(예: String, Vec)은 자동으로 Copy를 구현할 수 없으며, 이는 메모리의 이중 해제를 초래할 수 있습니다.
유형이 Copy를 구현하면, 다른 논리로 Clone을 수동으로 구현할 수 있나요?
네, Clone을 수동으로 구현할 수 있으며 논리가 다를 수 있지만, Copy와 Clone이 일관되도록 하는 것이 좋습니다: Copy는 할당 없이 Clone을 호출합니다.
#[derive(Copy)] struct X; impl Clone for X { fn clone(&self) -> X { *self } }
구조체가 Copy 필드만 포함되지만 #[derive(Copy)]로 표시되지 않으면 Copy가 됩니까?
아니요, 구성 때문에 유형이 자동으로 Copy가 되지 않으며, 유형에 대해 Copy를 명시적으로 파생해야 합니다.
힙 데이터를 가진 유형이 잘못된 Copy로 표시되어 종료 시 메모리의 이중 해제가 발생합니다.
장점:
단점:
Copy는 가벼운 구조(좌표, 색상)에 사용하고, Clone은 복잡한 구조(문자열, 벡터)에 사용합니다. 코드는 안전하고 예측 가능합니다.
장점:
단점: