왜 두 번째 impl을 추가하면 인수의 역 참조 강제가 방지됩니까?


10

impl Add<char> for String을 표준 라이브러리 에 추가하려고 할 때이 문제가 발생했습니다 . 그러나 운영자 shenanigans없이 쉽게 복제 할 수 있습니다. 우리는 이것으로 시작합니다 :

trait MyAdd<Rhs> {
    fn add(self, rhs: Rhs) -> Self;
}

impl MyAdd<&str> for String {
    fn add(mut self, rhs: &str) -> Self {
        self.push_str(rhs);
        self
    }
}

충분히 간단합니다. 이를 통해 다음 코드가 컴파일됩니다.

let a = String::from("a");
let b = String::from("b");
MyAdd::add(a, &b);

이 경우 두 번째 인수 표현식 ( &b)의 유형은 &String입니다. 그런 다음 참조 &str취소되고 함수 호출이 작동합니다.

그러나 다음 impl을 추가해 보겠습니다.

impl MyAdd<char> for String {
    fn add(mut self, rhs: char) -> Self {
        self.push(rhs);
        self
    }
}

( 운동장의 모든 것 )

이제 MyAdd::add(a, &b)위 의 표현식은 다음 오류로 이어집니다.

error[E0277]: the trait bound `std::string::String: MyAdd<&std::string::String>` is not satisfied
  --> src/main.rs:24:5
   |
2  |     fn add(self, rhs: Rhs) -> Self;
   |     ------------------------------- required by `MyAdd::add`
...
24 |     MyAdd::add(a, &b);
   |     ^^^^^^^^^^ the trait `MyAdd<&std::string::String>` is not implemented for `std::string::String`
   |
   = help: the following implementations were found:
             <std::string::String as MyAdd<&str>>
             <std::string::String as MyAdd<char>>

왜 그런 겁니까? 나에게 그것은 deref-coercion이 오직 하나의 함수 후보가있을 때만 수행되는 것처럼 보인다. 그러나 이것은 나에게 잘못된 것 같습니다. 규칙이 왜 그런가요? 나는 사양을 살펴 보았지만 인수 거부 강제에 대해서는 아무것도 찾지 못했습니다.


이것은 나 에게이 대답을 생각 나게한다 . 컴파일러는 일반적으로 특성을 알고 있으며 적용되는 특성이 하나만 있으면에 impl사용되는 유형 인수를 선택하여 명확하게 할 수 있습니다 impl. 다른 Q & A에서 나는이 기능을 사용하여 컴파일러가 (보일 수있는) impl호출 사이트에서를 선택하게 했습니다. 이는 일반적으로 할 수없는 것입니다. 아마도에서 가 DEREF 강제을 수행 할 수 있습니다 무엇 경우. 그러나 그것은 단지 추측 일뿐입니다.
trentcl

2
여기에 하나의 impl이 발견되면 컴파일러가 그것을 "열심히 확인"하여 (다른 것들 중에서도) deref 강제가 발생할 수 있음을 나타내는 주석 이 있습니다. 여러 임프 후보에 대해서는 발생하지 않습니다. 그래서 나는 그것이 일종의 대답이라고 생각하지만, 나는 더 많은 것을 알고 싶어합니다. rustc 서적 의이 장이 도움이 될 수 있지만, 내가 알 수있는 한, 이것에 대해 구체적으로 말하지는 않습니다.
Lukas Kalbertodt

답변:


0

직접 설명했듯이 컴파일러는 impl특별히 유효한 것이 하나만있는 경우를 처리하고 이를 사용하여 형식 유추를 구동 할 수 있습니다.

여기에 하나의 impl이 발견되면 컴파일러가 그것을 "열심히 확인"하여 (다른 것들 중에서도) deref 강제가 발생할 수 있음을 나타내는 주석 이 있습니다. 여러 임프 후보에 대해서는 발생하지 않습니다.

두 번째 부분은 역류 강요 가 예상되는 유형이 알려진 사이트에서만 발생하고 투기 적으로 발생하지 않는다는 것입니다. 참조의 강제 사이트 를 참조하십시오. Impl 선택 및 형식 유추는 먼저MyAdd::add(&str) 인수를 강요하기 위해 예상되는 것을 명시 적으로 찾아야합니다 &str.

해결 방법은이 상황에서 필요한 경우, 같은 식을 사용 &*b하거나 &b[..]또는 b.as_str()두 번째 인수에 대해.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.