Ich habe eine Struktur, die wir mit dem Builder-Muster erstellen können, da es einige Felder Option
al.Standard generischer Parameter
Wenn ich die Builder-Funktionen verwenden, um diese optionalen Felder anzugeben, muss ich die generischen Parameter nicht angeben.
Aber wenn ich diese Funktionen nicht aufrufen, muss ich die generischen Parameter angeben. Hier
ein Beispiel:
use Structs::*;
struct Struct<T, F: Fn(T)> {
func: Option<F>,
value: T,
}
enum Structs<T, F: Fn(T)> {
Struct1(T),
Struct2(T, F),
}
impl<T, F: Fn(T)> Struct<T, F> {
fn new(value: T) -> Struct<T, F> {
Struct {
func: None,
value: value,
}
}
fn build(self) -> Structs<T, F> {
if let Some(func) = self.func {
Struct2(self.value, func)
}
else {
Struct1(self.value)
}
}
fn func(mut self, func: F) -> Struct<T, F> {
self.func = Some(func);
self
}
}
fn main() {
let _strct = Struct::new(42)
.func(|n| { println!("{}", n); })
.build();
//let _strct = Struct::new(42).build(); // Does not compile.
let _strct = Struct::<_, &Fn(_)>::new(42).build();
}
Ich mag würde die Art Anmerkung verzichten, wenn die optionalen Felder nicht gesetzt ist, etwa so:
let _strct = Struct::new(42).build();
Es soll festgelegt werden, dass der F
Typ hängt von T
ab.
Ich habe versucht, einen Standard-Typ-Parameter als solche Angabe:
impl<T, F: Fn(T) = Box<Fn(T)>> Struct<T, F> {
aber das Problem nicht lösen.
Wie kann ich vermeiden, die Typparameter im Struct::new()
Aufruf angeben zu müssen?
Wenn es nicht möglich ist, dies zu vermeiden, gibt es Alternativen zum Builder-Muster, die es mir erlauben würden, die Typannotation wegzulassen?
Wenn Sie keinen konkreten Typ für 'T' oder' F' angeben, wie viel Raum sollte dann der Rust-Compiler zum Speichern von 'Struct' reservieren? – Shepmaster
@Shempmaster, in der Theorie, wenn der Compiler bestimmen kann, dass 'F' nie verwendet wird, kann es einfach dieses Feld als Größe 0 schreiben. Das Problem ist natürlich, dass diese Art der vollständigen Programmschlussfolgerung wirklich kompliziert ist. – LinearZoetrope
@Jsor ein interessanter Punkt, aber wie Sie erwähnen, macht Rust keine Inferenz über eine einzige Funktionsgrenze hinaus. – Shepmaster