Ich versuche, einige allgemeine mathematische Funktionen in Rust zu schreiben, und ich halte in die folgende Fehlermeldung ausgeführt wird:Rust: Lösen Merkmal impl Konflikte
error: conflicting implementations for trait SoAndSo
Ich möchte wissen, ob es möglich ist, das Problem zu lösen und wenn ja wie.
Zum Beispiel, ich versuche, ein generisches Punktprodukt zu schreiben, das zwei Iteratoren nimmt, reißt sie und iteriert über die Paare, um die Produkte zu akkumulieren. Aber ich möchte, dass diese Funktion auch komplexwertige Skalarprodukte berechnen kann. Das Skalarprodukt über komplexe Zahlen beinhaltet die Konjugation einer Seite. Meine erste Idee war, ein Merkmal Dot1
für eine binäre Funktion zu schreiben, um Mul
darin zu ersetzen, dass es auch das Argument der linken Seite konjugiert. Hier ist der vollständige Code:
extern crate num;
use num::complex::{Complex,Complex32,Complex64};
use std::num::Float;
trait Dot1<Rhs,Result> {
fn dot1(&self, rhs: Rhs) -> Result;
}
impl<T: Float> Dot1<T,T> for T { // conjugation for reals is a no-op
fn dot1(&self, rhs: T) -> T { *self * rhs }
}
impl<T: Num+Clone> Dot1<Complex<T>,Complex<T>> for Complex<T> {
fn dot1(&self, rhs: Complex<T>) -> Complex<T> { self.conj() * rhs }
}
fn main() {
println!("Hello, world!")
}
Da ein Complex<T>
nicht Float
, sollte es keine Überlappung betwen die beiden "generic impls". Daher erwarte ich keine Probleme. Aber jedes Mal wenn ich versuche, für ein Merkmal mehr als einen „generic impl“ zur Verfügung zu stellen, wird der Compiler mag es nicht:
<anon>:10:1: 12:2 error: conflicting implementations for trait `Dot1`
<anon>:10 impl<T: Float> Dot1<T,T> for T {
<anon>:11 fn dot1(&self, rhs: T) -> T { *self * rhs }
<anon>:12 }
<anon>:14:1: 16:2 note: note conflicting implementation here
<anon>:14 impl<T: Num+Clone> Dot1<Complex<T>,Complex<T>> for Complex<T> {
<anon>:15 fn dot1(&self, rhs: Complex<T>) -> Complex<T> { self.conj() * rhs }
<anon>:16 }
<anon>:14:1: 16:2 error: conflicting implementations for trait `Dot1`
<anon>:14 impl<T: Num+Clone> Dot1<Complex<T>,Complex<T>> for Complex<T> {
<anon>:15 fn dot1(&self, rhs: Complex<T>) -> Complex<T> { self.conj() * rhs }
<anon>:16 }
<anon>:10:1: 12:2 note: note conflicting implementation here
<anon>:10 impl<T: Float> Dot1<T,T> for T {
<anon>:11 fn dot1(&self, rhs: T) -> T { *self * rhs }
<anon>:12 }
<anon>:14:1: 16:2 error: failed to find an implementation of trait core::num::Float for num::complex::Complex<T>
<anon>:14 impl<T: Num+Clone> Dot1<Complex<T>,Complex<T>> for Complex<T> {
<anon>:15 fn dot1(&self, rhs: Complex<T>) -> Complex<T> { self.conj() * rhs }
<anon>:16 }
Wie kann ich einen generischen, Iterator-basierten Skalarprodukt schreiben, die für beiden Werke: real und komplexe Zahlen? Die Iteratoren zu nehmen, sie zu zippen, usw. ist kein Problem und ich konnte sogar herausfinden, welche Typparameter mit welchen Grenzen verwendet werden sollten. Aber ich bin nicht in der Lage, bestimmte Datentypen mit Merkmalen wie der oben genannten zu "vereinheitlichen".
dies wird möglich sein, wenn [PR 48] (https://github.com/rust-lang/rfcs/pull/48) – Arjan