ฉันเจอปัญหานี้เมื่อพยายามเพิ่มความหมาย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>>
ทำไมถึงเป็นอย่างนั้น? สำหรับฉันดูเหมือนว่าการขู่เข็ญจะกระทำเมื่อมีผู้สมัครเพียงคนเดียวเท่านั้น แต่นี่ดูเหมือนผิดสำหรับฉัน ทำไมกฎจะเป็นเช่นนั้น ฉันพยายามตรวจสอบสเปค แต่ฉันไม่พบอะไรเลยในการโต้เถียง
impl
impl
ในคำถามอื่น ๆ ฉันใช้ความสามารถนี้เพื่อทำให้คอมไพเลอร์ (ปรากฏ) เลือกimpl
ไซต์การโทรซึ่งเป็นสิ่งที่ปกติไม่สามารถทำได้ ในกรณีนี้น่าจะเป็นสิ่งที่ยอมให้ถูกบังคับขู่เข็ญ แต่นั่นเป็นเพียงการเดา