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 강제을 수행 할 수 있습니다 무엇 경우. 그러나 그것은 단지 추측 일뿐입니다.