मैं इस मुद्दे पर आया जब Add<char> for String
मानक पुस्तकालय में निहित जोड़ने की कोशिश कर रहा था । लेकिन हम इसे आसानी से दोहरा सकते हैं, ऑपरेटर शेंनिगन के बिना। हम इसके साथ शुरू करते हैं:
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
। यह तो deref-coerced में &str
और फ़ंक्शन कॉल कार्य करता है।
हालाँकि , चलिए निम्नलिखित जोड़ जोड़ने का प्रयास करते हैं:
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>>
ऐसा क्यों है? मेरे लिए ऐसा लगता है कि डेरेफ़-ज़बरदस्ती केवल तब की जाती है जब केवल एक फ़ंक्शन उम्मीदवार होता है। लेकिन यह मुझे गलत लगता है। नियम ऐसे क्यों होंगे? मैंने विनिर्देशन के माध्यम से देखने की कोशिश की, लेकिन मुझे तर्क के डर पर कुछ भी नहीं मिला है।
impl
लागू होता है, तो इसमें उपयोग किए गए प्रकार के तर्क को चुनकर इसे खंडित किया जा सकता हैimpl
। अन्य प्रश्नोत्तर में मैंनेimpl
कॉल करने के लिए कंपाइलर (दिखने) के लिए इस क्षमता का उपयोग किया , जो आमतौर पर ऐसा कुछ होता है। संभवत: इस मामले में यह वही है जो इसे डेरेफ़ ज़बरदस्ती करने की अनुमति देता है। लेकिन यह केवल एक अनुमान है।