Utility Traits - Clone, Copy

이정후·2023년 8월 11일
0

Rust

목록 보기
9/13
post-thumbnail

Clone

std::clone::Clone은 자기 자신의 복사본을 만들 수 있는 타입을 위한 트레이트이다.

trait Clone: Sized {
	fn clone(&self) -> Self;
    fn clone_from(&mut self. source: &Self) {
    	*self = source.clone()
    }
}

clone메소드는 self의 복사본을 만들어 리턴한다. Clone 트레이트가 Sized 트레이트를 가지고 있는 이유는 함수는 unsized 값을 반환하지 않기 때문이다.

값을 Clone 할 때는 그 값이 소유한 모든 것이 복사되어야 한다. 그렇기 때문에 clone은 시간과 메모리를 많이 소비할 가능성이 높다.

예를들어 Vec<String>을 복사하면 벡터만 복사되는것이 아니라 내부의 String의 요소까지 전부 복사된다.
Rc<T>, Arc<T>는 레퍼런스 카운터만 증가한 새로운 포인터가 리턴된다.

clone_from

clone_from 메소드는 source 복사본을 가지고 self의 값을 수정한다.
타입이 같은 경우에는 불필요한 힙 해제와 할당의 과정을 거치지 않고 조금 더 최적화된 작업을 수행할 수 있다.

다만 Clone을 구현할 때 대상이 되는 타입의 필드나 요소를 간단히 clone해서 얻은 복사본으로 새로운 값을 만들 수 있다면 굳이 직접 구현할 필요는 없다. 다만 #[derive(Clone)]을 해당 타입 위에 정의하도록 하자

정리

표준 라이브러리에서 복사해도 되는 타입들은 대부분 다 Clone을 구현하고 있다. (bool, i32등)
clone은 절대 실패해서는 안된다. std::fs::File 값은 타입은 복사할 수 있지만 메모리 등이 부족하면 실패 할 수 있다. 그러므로 Clone을 구현하지 않는데, 다만 Result를 반환하는 try_clone메소드를 사용해서 실패 여부를 알 수 있다.

Copy

std::marker::Copy 를 구현하는 트레이트

trait Copy: Clone{}

단 Copy는 바이트 단위의 얕은 복사만 수행하는 타입에서만 사용할 수 있다. 힙 할당이나 운영체제 등에서는 사용할 수 없다. Drop 트레이트를 가지고 있는 모든 타입은 Copy가 될 수 없다.

Clone과 마찬가지로 Copy도 #[derive(Copy)]를 사용하여 Rust에게 대신 구현하도록 요청할 수 있다. #[derive(Clone, Copy)]를 주로 많이 사용한다.

Copy는 신중히 사용해야 한다. 타입이 쓰기 수월할지는 모르겠으나, 구현에는 상당한 어려움이 따를 수 있다. 복사비용 역시 클 수 있음을 유의하자.

profile
꾸준하게

0개의 댓글