Piszę wiązanie Rust dla biblioteki C. Implementuje encję, która może być zbudowana z różnych elementów źródłowych, prawdopodobnie zapisując wewnętrznie pewne referencje. Chcę, aby typ rdzy wymuszał bezpieczną politykę praw własności, w związku z czym struktura opakowania jest generyczna, sparametryzowana przez typ przechowywanego odwołania.Opis typu jawnego dla generycznego konstruktora generycznego typu
struct Foobar<T> {
origin: T,
}
Następnie implementuję niektóre konstruktory dla mojego typu Foobar
.
impl<T> Foobar<T> {
fn from_nowhere() -> Foobar<()> {
Foobar { origin:() }
}
fn from_orange<F>(orange: &mut F) -> Foobar<&mut F>
where F: Orange
{
Foobar { origin: orange }
}
fn from_callback<F>(callback: F) -> Foobar<F>
where F: FnMut(u64) -> u64
{
Foobar { origin: callback }
}
}
I tu pojawia się problem: zarówno struct, jak i konstruktor są niezależnie sparametryzowane. Podczas gdy parametr typu konstruktora można wywnioskować z jego argumentów, parametr typu struct nie jest używany w konstruktorze i nie można go wywnioskować. Tak więc, naiwny sposób wywoływania konstruktora
let a = Foobar::from_nowhere();
let b = Foobar::from_orange(&mut fruit);
let c = Foobar::from_callback(|x| x*x);
myli rustc:
rustgen.rs:43:13: 43:33 error: unable to infer enough type information about `_`; type annotations required [E0282]
rustgen.rs:43 let a = Foobar::from_nowhere();
To może być ustalona poprzez zapewnienie jakiś dowolny parametr typu:
let a = Foobar::<()>::from_nowhere();
let b = Foobar::<()>::from_orange(&mut fruit);
let c = Foobar::<()>::from_callback(|x| x*x);
... co jest wszystko rodzaje brzydkie. Innym sposobem rozwiązania problemu byłoby przekształcenie konstruktorów w wolne funkcje, choć byłoby to (rodzaj) nie-idiomatyczne.
Pytanie brzmi: czy czegoś brakuje? Wygląda na to, że projekt jest wadliwy. Jaki byłby właściwy sposób zaprojektowania tego typu, aby uciec tylko z jednym poziomem generycznych?
Minimal reproducible example on Rust playpen
Dla porównania, moja wersja kompilatora jest:
$ rustc --version
rustc 1.1.0-dev (built 2015-04-26)
Dziękujemy! Nie zdawałem sobie sprawy, że możliwe jest posiadanie wielu klauzul "impl" dla różnych parametryzacji. –