Zunächst möchte ich sagen, dass das Problem nichts mit der Syntax impl Trait
zu tun hat. Ich habe die Schließung in eine benannte Struktur umgewandelt und die gleichen Ergebnisse erhalten.
Sehen wir uns nun den Code an, mit dem Sie arbeiten möchten:
%Vor%Was sagt der Compiler dazu?
%Vor%OK, also haben wir den Typ X und er muss das Merkmal Y implementieren, tut es aber nicht. Aber schauen wir genau hin:
%Vor% Ah ha! filter
erwartet eine Funktion, die einen Verweis auf einen Verweis auf ein Tupel akzeptiert, während die Funktion, die wir übergeben, einen Verweis auf ein Tupel akzeptiert. filter
übergibt eine Referenz an eine Referenz, weil tuples.iter()
über Referenzen iteriert, und filter
übergibt Referenzen an diese Referenzen.
Okay, lassen Sie uns die Definition von second
so ändern, dass Referenzen auf Referenzen akzeptiert werden:
Der Compiler ist immer noch nicht glücklich:
%Vor% expected bound lifetime parameter , found concrete lifetime
... Was bedeutet das?
f
ist ein Typ, der FnMut(&'c &'b (&'a str, &Fn(i32) -> bool)) -> bool
implementiert. Im Aufruf von apply
, B == &'c &'b (&'a str, &Fn(i32) -> bool)
und C == bool
. Beachten Sie, dass B
hier ein fester Typ ist; 'c
repräsentiert eine feste Lebensdauer, die eine konkrete Lebensdauer genannt wird.
Schauen wir uns die Signatur von filter
an:
Hier muss P
FnMut(&Self::Item) -> bool
implementieren. Eigentlich ist diese Syntax eine Abkürzung für for<'r> FnMut(&'r Self::Item) -> bool
. Hier. 'r
ist ein gebundener Lebensdauerparameter.
Das Problem ist also, dass unsere Funktion, die FnMut(&'c &'b (&'a str, &Fn(i32) -> bool)) -> bool
implementiert, nicht for<'r> FnMut(&'r Self::Item) -> bool
implementiert. Wir benötigen eine Funktion, die for<'c> FnMut(&'c &'b (&'a str, &Fn(i32) -> bool)) -> bool
implementiert. Der einzige Weg, dies zu tun, wäre im Moment, apply
so zu schreiben:
oder die explizitere Version:
%Vor%Wenn Rust schließlich höherstufige Typen , dort könnte ein eleganterer Weg sein, um dieses Problem zu lösen.
Tags und Links closures rust trait-objects