দ্বিতীয় প্রেরণা যুক্তি যুক্তির জোর করে কেন আটকাচ্ছে?


10

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। এরপরে এটি ডেরেফ-জোর করা হয় &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কল সাইটে একটি সংকলক (উপস্থিত) চয়ন করতে তৈরি করেছিলাম যা এটি সাধারণত না করতে পারে। সম্ভবত এ এই ক্ষেত্রে যে তা deref বলপ্রয়োগ করার অনুমতি দিয়েছে। তবে এটি কেবল অনুমান।
ট্রেন্টক্লা

2
এখানে এমন একটি মন্তব্য রয়েছে যা জানিয়েছে যে কেবলমাত্র একটি ইমপ্লের সন্ধান পেলে সংকলকটি এটি "আগ্রহের সাথে নিশ্চিত করে", যা ডেরেফ জবরদস্তি (অন্যান্য বিষয়গুলির মধ্যে) ঘটতে দেয়। এটি একাধিক প্রার্থী প্রার্থীদের ক্ষেত্রে ঘটে না। সুতরাং আমি অনুমান করি যে এটির মতো উত্তর, তবে আমি আরও জানতে আগ্রহী। দেহাতি বইয়ের এই অধ্যায়টি সাহায্য করতে পারে, তবে যতদূর আমি বলতে পারি, এটি এ সম্পর্কে বিশেষভাবে কিছু বলে না।
লুকাশ কালবার্তোড

উত্তর:


0

যেমন আপনি নিজের ব্যাখ্যা করেছেন, সংকলকটি সেই ক্ষেত্রে আচরণ করে যেখানে implবিশেষভাবে কেবলমাত্র একটি বৈধ আছে , এবং এটি টাইপ অনুক্রমটি ড্রাইভ করতে ব্যবহার করতে পারে:

এখানে এমন একটি মন্তব্য রয়েছে যা জানিয়েছে যে কেবলমাত্র একটি ইমপ্লের সন্ধান পেলে সংকলকটি এটি "আগ্রহের সাথে নিশ্চিত করে", যা ডেরেফ জবরদস্তি (অন্যান্য বিষয়গুলির মধ্যে) ঘটতে দেয়। এটি একাধিক প্রার্থী প্রার্থীদের ক্ষেত্রে ঘটে না।

দ্বিতীয় অংশটি হ'ল ডেরেফ জবরদস্তি কেবলমাত্র সেই জায়গাগুলিতেই ঘটবে যেখানে প্রত্যাশিত ধরণটি জানা যায়, এটি অনুমানমূলকভাবে ঘটে না। রেফারেন্সে জবরদস্তি সাইটগুলি দেখুন । ইমপ্লিকেশন নির্বাচন এবং প্রকারের অনুমানটি প্রথমে স্পষ্টভাবে খুঁজে পাওয়া উচিত যা MyAdd::add(&str)প্রত্যাশিত হবে, যাতে যুক্তিটি জোর করে দেখার চেষ্টা করতে হবে &str

একটি ওয়ার্কঅ্যারাউন্ড এই অবস্থায় প্রয়োজন হলে, মত একটি অভিব্যক্তি ব্যবহার &*bবা &b[..]বা b.as_str()দ্বিতীয় যুক্তি জন্য।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.