Impl'yi Add<char> for String
standart kütüphaneye eklemeye çalışırken bu sorunla karşılaştım . Ancak operatör maskaralıkları olmadan kolayca çoğaltabiliriz. Bununla başlıyoruz:
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
}
}
Yeterince basit. Bununla, aşağıdaki kod derlenir:
let a = String::from("a");
let b = String::from("b");
MyAdd::add(a, &b);
Bu durumda, ikinci bağımsız değişken ifadesinin ( &b
) türüne sahip olduğunu unutmayın &String
. Sonra deref zorlanır &str
ve işlev çağrısı çalışır.
Ancak , aşağıdaki implleri eklemeyi deneyelim:
impl MyAdd<char> for String {
fn add(mut self, rhs: char) -> Self {
self.push(rhs);
self
}
}
Şimdi MyAdd::add(a, &b)
yukarıdaki ifade aşağıdaki hataya yol açar:
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>>
Neden? Bana göre deref-zorlama sadece bir işlev adayı olduğunda yapılıyor gibi görünüyor. Ama bu benim için yanlış görünüyor. Kurallar neden böyle olsun ki? Şartnameye bakmayı denedim, ama deref zorlama argümanı hakkında hiçbir şey bulamadım.
impl
geçerli olduğunda, bu türde kullanılan tür bağımsız değişkenini seçerek belirsizleşebilirimpl
. Diğer Soru-Cevap bölümünde, bu yeteneği derleyicininimpl
arama sitesinde bir seçim yapmak (görünüşe göre) yapmak için kullandım , ki bu genellikle yapamayacağı bir şeydir. Muhtemelen bu durumda deref zorlaması yapmasına izin veren şey budur. Ama bu sadece bir tahmin.