2016-07-11 2 views
3

는 그문자열을 포함하는 복사 가능 구조체를 정의하는 방법은 무엇입니까?

#[derive(Copy, Clone)] 
enum Command { 
    Quit, 
    Error { msg: String }, 
} 

컴파일러 같은 구조체가 Error에 대한 복사 생성자를 생성 할 수 없습니다 불평합니다.

채널을 통해 다른 스레드로 전달할 수 있도록 복사 가능 구조체를 만들어야합니다. msgi32 경우

error: the trait `Copy` may not be implemented for this type; variant `Error` does not implement `Copy` [E0205] 
#[derive(Copy, Clone)] 
^~~~~~~~~~~~~~~~~~~~~~ 
note: in this expansion of #[derive_Copy] (defined in src/main.rs) 

그것은 컴파일합니다. 그런 기본적인 유형이 String으로 복사가 불가능하다는 것이 이상합니다.

+0

'문자열'은 'Vec'과 같은 방식으로 '복사 가능'하지 않습니다. 둘 다 힙 할당 콘텐츠를 처리하므로'memcpy '로 안전하게 복사 할 수 없습니다. 책의 관련 페이지 : https://doc.rust-lang.org/book/strings.html –

+0

볼 수는 있지만 객체를 채널에 전달해야하며 유형을 복사 할 수 있어야합니다. 이 자습서는 표지에서부터 읽으므로 잘 읽지 만 얕은 편입니다. –

+2

@ DaneelS.Yaitskov 형식은 채널을 통과하기 위해 복사 할 수 없어야합니다 *. –

답변

7

나를 위해 문자열과 같은 기본 유형을 복사 할 수 없다는 것이 이상하게 보입니다.

녹 색은 명시 적으로입니다.

C 프로그래머 (그리고 가장 주목할만한 것은 Linus Torvald)가 C++와 관련하여 들었던 것은 C++에서 너무 많은 암시적인 복사가있어 메모리 할당이 숨겨져 있다는 것입니다. 암시 적 전환과 함께, 그들은 예기치 않은 장소에서 실제로 크롤링 할 수 있습니다.

대신 녹말은 기본 작업의 복잡성을 드러내는 의도로 설계되었습니다. 암묵적으로 일부 변환을 수행하지만 (&T에서 &Trait까지) 저렴하고 (일반적으로 일정한 시간)입니다.

이 명확성이 두 특성에 보여줍니다 당신은 여기에 있습니다 :

  • Clone 새로운 인스턴스를 생성하는 방법을를 나타내는에 대해, 그리고 명시 적으로 호출해야합니다. 대부분의 유형 (전부는 아님)은이를 사용하여 복사 할 수 있습니다.

  • Copy은 개발자가 형식에 대한 암시 적 복사를 활성화하려고한다는 것을 나타내는 특정 컴파일러 특성입니다.

    • String : 얕은 사본에는 메모리 할당이 발언을 보장하기 위해,

    그래서 그 암시 사본의 일부로서 발생하지 않습니다 보장하는 딥 카피 일치하는 경우에만 사용할 수 있습니다 그 이외의 명백한 메모리 할당이 발생할 것이기 때문 복사 가능한 것입니다, .clone()

  • String 암시 복사 가능한 아닌 사용
3

String은 효과적으로 힙 할당 된 데이터에 대한 포인터이며 길이와 용량입니다. 이 정보를 복사하면 두 개의 소유 변수가 만들어지며, 둘 다 동일한 힙에 할당 된 데이터를 가리키게됩니다. 그러면 Rust의 메모리 관리가 중단됩니다 (사용 후 자유 문제로 이어질 것입니다).당신의 구조체 Copy이 채널을 통해 전송 될 구현할 필요가 없습니다 말했다

, 그냥, (포인터의 크기는 컴파일러에 알려져 있기 때문에) StringSized 할 필요가있다. String과 함께 구조체 또는 열거 형을 보내면 어떤 특성을 도출하지 않고도 즉시 사용할 수 있습니다.

관련 문제