2015-01-17 3 views
18

두 요소 Vector 구조체를 만들었으므로 + 연산자에 과부하를 걸고 싶습니다.구조체에 대한 참조에 특성 추가 기능을 구현하려면 어떻게해야합니까?

필자의 모든 함수와 메서드가 값이 아닌 참조를 취하고 + 연산자가 같은 방식으로 작동하기를 원합니다.

impl Add for Vector { 
    fn add(&self, other: &Vector) -> Vector { 
     Vector { 
      x: self.x + other.x, 
      y: self.y + other.y, 
     } 
    } 
} 

어떤 변형을 시도 하느냐에 따라 평생 문제가 발생하거나 유형이 일치하지 않습니다. 특히 &self 인수가 올바른 유형으로 취급되지 않는 것으로 보입니다.

템플릿 인수가 impl이고 Add 인 예제를 보았지만 다른 오류가 발생했습니다.

찾았지만 use std::ops::Mul;을 맨 위에 넣어도 응답 코드가 작동하지 않습니다.

I는 "참조를 사용하는 이유, 당신은 두 개의 필드가"

내가 동의하지 않습니다 (ed530d7a3 2015년 1월 16일 22시 41분 16초 0000) rustc 1.0.0-야간를 사용하고 답변; 100 요소 구조체를 원한다면 어떻게 될까요? 큰 구조체라도 값으로 전달해야한다는 답변을 받아 들일 것입니다. (그렇다고 생각하지 않습니다.) 구조체 크기에 대한 좋은 규칙을 알고 싶습니다. 값 대 구조체를 통해 전달하지만 현재의 질문은 아닙니다.

+0

"100 요소 구조체를 원한다면 무엇을해야합니까?"- Rust는 RVO와 같은 최적화를 사용하여 적절한 경우 적절한 참조와 더 나은 선택을 사용합니다. – Shepmaster

+0

@Shepmaster : RVO는 반환 값에 영향을 줄 것입니다. 반환 값은 값으로 반환됩니다. 큰 구조체의 특성을 값으로 구현해야한다는 것을 보여주는 문서를 가리킬 수 있습니까? –

+1

필자가 아는 최고의 문서는 [포인터 반환에 관한 장] (http://doc.rust-lang.org/book/pointers.html#returning-pointers)입니다. 그러나, 나는 큰 구조체를 추가하는 예제를 만들었고 (http://is.gd/25ITa7) 생성 된 LLVM을 체크했다. (약간 구조체가 정리되었다.)'(% struct.Big * sret, % struct.Big *, % struct.Big *)'. LLVM 전문가라고 주장하지는 않지만 자동으로 참조로 돌아가는 것처럼 보입니다. – Shepmaster

답변

28

Vector이 아니라 &VectorAdd을 구현해야합니다. 그 정의에

impl<'a, 'b> Add<&'b Vector> for &'a Vector { 
    type Output = Vector; 

    fn add(self, other: &'b Vector) -> Vector { 
     Vector { 
      x: self.x + other.x, 
      y: self.y + other.y, 
     } 
    } 
} 

Add::add는 항상 값에 의해 self 걸립니다. 그러나 참조는 다른 과 같은 유형이므로 특성을 구현할 수도 있습니다. 특성이 참조 유형에 구현되면 self 유형이 참조입니다. 참조는 값에 의해 전달됩니다. 일반적으로 Rust에서 값을 전달하는 것은 소유권을 이전 함을 의미하지만, 참조로 값을 전달할 때 참조가 변경 될 경우 해당 참조를 단순히 복사 (또는 변경/이동하면 됨)하고 참조의 소유권을 이전하지 않습니다 (참조가 처음에 그 지시 대상을 소유하지 않음). 이 모든 것을 고려할 때 Add::add (및 다른 많은 연산자)은 값으로 self을 가져야합니다. 피연산자의 소유권을 가져와야하는 경우 Add을 structs/enums에 직접 구현할 수 있으며, 그렇지 않으면 다음을 수행 할 수 있습니다. 참조에 Add을 구현하십시오.

여기서 self은 을 구현하는 유형이기 때문에 &'a Vector입니다.

또한 두 입력 매개 변수의 수명이 서로 관련이 없다는 사실을 강조하기 위해 수명이 다른 RHS 유형 매개 변수를 지정했습니다.


1 사실, 참조 형식은, 당신은 또한 허용하고 당신이 T에 대한 특성을 구현할 수있는 경우 즉, 당신의 상자 (정의 유형에 대한 참조에 대한 특성을 구현할 수 있다는 점에서 특별하다 &T에 대해 구현). &mut TBox<T>의 동작은 동일하지만 일반적으로 U<T>에 해당하지 않습니다. 여기에서 U은 동일한 크레이트에 정의되어 있지 않습니다.

+3

"Add :: add는 항상 값으로 자기를 취한다. 우리가 Add on을 구현하는 타입이기 때문에 & 'a Vector 타입입니다. "이것은 특성이 참조 용인지 아닌지에 따라 자기 타입이 변경된다는 핵심 정보입니다. 감사합니다. –

+2

와우. 놀랍습니다. 이것이 올바른 답이면서도 그것이 맞다는 것입니다.이 모든 것은 상당히 직관적 인 것으로 느껴질 수 있습니다. 참조가 문제인지에 대한 레시피와 같은 느낌인지에 따라 두 가지 다른 방식으로 Add를 정의 할 수 있습니다. – Squirrel