Ein einfaches Programm, um dieses Verhalten zu zeigen:Warum steht die Trait-Implementierung für Box <T> in Konflikt mit Fn()?
use std::boxed::Box;
struct Cow;
trait CanSpeak {
fn speak(&self);
}
impl CanSpeak for Cow {
fn speak(&self) {
println!("moo");
}
}
impl<F: Fn()> CanSpeak for F {
fn speak(&self) {
self();
}
}
impl<T: CanSpeak> CanSpeak for Box<T> {
fn speak(&self) {
(**self).speak()
}
}
fn lol_speak() {
println!("lol")
}
fn lets_speak<T: CanSpeak>(t: & T) {
t.speak();
}
fn main() {
let cow = Cow;
lets_speak(&cow);
lets_speak(&lol_speak);
let boxed_cow = Box::new(Cow);
lets_speak(&boxed_cow);
}
Compilation nicht mit:
test.rs:15:1: 19:2 error: conflicting implementations for trait `CanSpeak` [E0119]
test.rs:15 impl<F: Fn()> CanSpeak for F {
test.rs:16 fn speak(&self) {
test.rs:17 self();
test.rs:18 }
test.rs:19 }
test.rs:15:1: 19:2 help: run `rustc --explain E0119` to see a detailed explanation
test.rs:21:1: 25:2 note: note conflicting implementation here
test.rs:21 impl<T: CanSpeak> CanSpeak for Box<T> {
test.rs:22 fn speak(&self) {
test.rs:23 (**self).speak()
test.rs:24 }
test.rs:25 }
error: aborting due to previous error
Meine Fragen sind:
- As far as I can tell
Box<T>
nicht implementiertFn()
Merkmal. Warum schlägt das obige Beispiel fehl? - Was ist die korrekte Implementierung für das, was ich versuche zu tun?
Ich habe gerade angefangen zu lernen Rust. Danke für Ihre Hilfe.
Dank Chris, aber ich fürchte, ich es immer noch nicht bekommen . Kannst du erklären, was "Box" in diesem Fall besonders macht, dass Rust denkt, dass es einen Konflikt geben kann? Zum Beispiel Wenn, ich verstehe Ihre Erklärung richtig, irgendein Container, sagen wir 'Arc' sollte auch Konflikt, weil 'T' kann' CanSpeak' implementieren und 'Arc ' kann 'Fn()' implementieren. Aber "Box" in meinem Beispiel mit "Arc" zu ersetzen funktioniert gut. –
Vikas
Es gibt * nichts * Besonderes daran. Es gibt nur zwei generische Implementierungen für ein Merkmal, die sich überschneiden können. –
Warum funktioniert 'Arc'? In meinem Beispiel, wenn ich "Box" durch "Arc" ersetze, kompiliert es ohne irgendwelche Fehler. – Vikas