Rust의 Copy vs. Clone: 무엇이 다를까?
Grace Collins
Solutions Engineer · Leapcell

좋은 형제: Rust의 Copy와 Clone
Rust에서 Copy 및 Clone 트레이트는 타입의 복사 동작을 제어합니다. 이를 통해 타입의 값이 어떻게 복사되는지, 어떤 상황에서 복사가 허용되는지 정의할 수 있습니다. 이 글에서는 이러한 두 트레이트의 목적과 사용법을 자세히 소개하고, 사용법을 보여주는 코드 예제를 함께 제공합니다.
Copy 트레이트
Copy 트레이트는 타입이 비트 단위로 복사될 수 있음을 나타냅니다. 타입이 Copy 트레이트를 구현하면 해당 타입의 값은 할당, 인수로 전달, 반환될 때 자동으로 복제됩니다.
Copy 트레이트란 무엇인가요?
Copy 트레이트는 마커 트레이트입니다. 즉, 어떤 메서드도 정의하지 않습니다. 단순히 타입을 비트 단위 복사에 적합한 것으로 표시합니다.
#[derive(Copy)] struct Point { x: i32, y: i32, }
Copy 트레이트를 구현하는 방법은 무엇인가요?
Copy 트레이트를 구현하려면 타입 정의에 #[derive(Copy)] 어트리뷰트를 추가해야 합니다. 또한, Copy를 구현하는 모든 타입은 Clone도 구현해야 합니다.
#[derive(Copy, Clone)] struct Point { x: i32, y: i32, }
Clone을 구현하지 않고 Copy를 구현하려고 하면 컴파일러가 오류를 발생시킵니다.
#[derive(Copy)] struct Point { x: i32, y: i32, } // error[E0277]: the trait bound `Point: std::clone::Clone` is not satisfied
오류 메시지는 Point 타입이 Clone 트레이트를 구현하지 않았으므로 Copy를 구현할 수 없음을 나타냅니다.
이러한 요구 사항이 존재하는 이유는 모든 Copy 타입은 Clone도 구현해야 하기 때문입니다. clone 메서드를 명시적으로 호출하면 Rust는 복사본을 만들려고 한다고 가정하고 복사 동작이 잘 정의되어 있는지 확인하려고 합니다. 따라서 Copy를 구현하려면 Clone도 구현해야 합니다.
어떤 타입이 Copy를 구현할 수 있나요?
모든 타입이 Copy를 구현할 수 있는 것은 아닙니다. 다음 기준을 충족하는 타입만 가능합니다.
- 타입 자체가 Plain Old Data (POD) 타입이어야 합니다. 즉, 포인터나 참조를 포함하지 않아야 합니다.
- 타입의 모든 필드도
Copy를 구현해야 합니다.
예를 들어, 다음 타입은 참조 필드를 포함하므로 Copy를 구현 할 수 없습니다.
struct Foo<'a> { x: &'a i32, } // error[E0204]: the trait `Copy` may not be implemented for this type impl Copy for Foo<'_> {}
왜 Copy 트레이트가 필요할까요?
Copy 트레이트를 사용하면 타입의 복사 동작을 제어할 수 있습니다. 타입이 Copy를 구현하면 해당 값은 할당, 함수 매개변수 전달 및 반환 시 자동으로 복제됩니다. 이렇게 하면 값을 복사하기 위해 clone()을 명시적으로 호출할 필요가 없습니다.
또한 Copy 타입은 항상 비트 단위 복사를 수행하므로 성능 오버헤드가 최소화됩니다. 이는 Rust 프로그램에서 성능을 최적화하는 데 특히 유용합니다.
Clone 트레이트
Copy와 달리 Clone 트레이트를 사용하면 타입의 값을 명시적으로 복사할 수 있습니다. 타입이 Clone을 구현하면 clone() 메서드를 호출하여 새 인스턴스를 만들 수 있습니다.
Clone 트레이트란 무엇인가요?
Copy와 달리 Clone은 clone()이라는 메서드를 포함하는 일반 트레이트입니다. 이 메서드는 값의 새 복사본을 만드는 역할을 합니다.
#[derive(Clone)] struct Point { x: i32, y: i32, }
Clone 트레이트를 구현하는 방법은 무엇인가요?
Clone 트레이트를 구현하려면 #[derive(Clone)] 어트리뷰트를 추가하거나 clone() 메서드를 수동으로 구현하면 됩니다.
#[derive(Clone)] struct Point { x: i32, y: i32, } // `clone()` 메서드를 수동으로 구현합니다. impl Clone for Point { fn clone(&self) -> Self { Self { x: self.x, y: self.y } } }
어떤 타입이 Clone을 구현할 수 있나요?
거의 모든 타입이 Clone을 구현할 수 있습니다. 값의 새 복사본을 만드는 방법을 정의할 수 있는 한 Clone을 구현할 수 있습니다.
왜 Clone 트레이트가 필요할까요?
Clone 트레이트를 사용하면 값을 명시적으로 복제할 수 있습니다. 이는 포인터나 참조를 포함하는 타입과 같이 비트 단위로 복사 할 수 없는 타입에 특히 유용합니다.
또한 Clone을 사용하면 복사 프로세스를 사용자 지정할 수 있습니다. clone() 메서드 내부에 필요한 로직을 추가하여 복사 중에 특정 작업을 수행할 수 있습니다.
Copy와 Clone의 차이점과 관계
Copy와 Clone은 모두 타입이 복사되는 방식을 제어하지만 주요 차이점이 있습니다.
Copy는 타입이 비트 단위 복사를 지원함을 나타내는 마커 트레이트입니다. 타입이Copy를 구현하면 해당 값은 할당, 함수 인수로 전달 및 반환 시 자동으로 복제됩니다.Clone은clone()이라는 메서드를 포함하는 일반 트레이트입니다. 타입이Clone을 구현하면clone()을 명시적으로 호출하여 새 복사본을 만들 수 있습니다.
또한 모든 Copy 타입은 Clone도 구현해야 합니다. 이렇게 하면 clone()을 명시적으로 호출할 때 Rust는 사용자가 무엇을 하는지 안다고 가정하고 비트 단위 복사를 허용합니다.
예제 분석
다음은 Copy와 Clone의 사용법을 보여주는 예제입니다.
#[derive(Copy, Clone)] struct Point { x: i32, y: i32, } fn main() { let p1 = Point { x: 1, y: 2 }; let p2 = p1; // 자동으로 복사됨 let p3 = p1.clone(); // 명시적으로 복사됨 }
이 예제에서는 Point 타입을 정의하고 Copy 및 Clone 트레이트를 모두 구현합니다. main 함수에서는 Point 값을 만들고 다른 변수에 할당합니다. Point가 Copy를 구현하므로 할당 작업은 값을 자동으로 복제합니다. 또한 clone()을 명시적으로 호출하여 값의 다른 복사본을 만듭니다.
Leapcell에서 Rust 프로젝트를 호스팅하세요.
Leapcell은 차세대 서버리스 플랫폼으로 웹 호스팅, 비동기 작업 및 Redis를 제공합니다.
다국어 지원
- Node.js, Python, Go 또는 Rust로 개발하세요.
무제한 프로젝트를 무료로 배포
- 사용량에 대해서만 지불하세요. 요청도, 요금도 없습니다.
압도적인 비용 효율성
- 유휴 요금 없이 사용한 만큼만 지불하세요.
- 예: $25로 평균 응답 시간이 60ms인 요청 694만 건을 지원합니다.
간소화된 개발자 경험
- 간편한 설정을 위한 직관적인 UI
- 완전 자동화된 CI/CD 파이프라인 및 GitOps 통합
- 실행 가능한 통찰력을 위한 실시간 메트릭 및 로깅
손쉬운 확장성 및 고성능
- 고도의 동시성을 쉽게 처리할 수 있는 자동 확장
- 운영 오버헤드가 전혀 없습니다. 빌드에만 집중하세요.
문서에서 자세히 알아보세요!
X에서 팔로우하세요: @LeapcellHQ



