我正在为一个C库编写Rust绑定。它实现了一个可以从不同源实体构建的实体,并可能在内部保存一些引用。我希望Rust类型能够强制执行安全的所有权策略,因此包装器结构是通用的,由存储引用类型的参数化。
struct Foobar<T> {
origin: T,
}
然后,我为我的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 }
}
}
问题来了:结构体和构造函数都是独立参数化的。虽然构造函数类型参数可以从其参数中推断出来,但结构体类型参数在构造函数中没有使用,因此无法推断。因此,调用构造函数的朴素方法如下:
let a = Foobar::from_nowhere();
let b = Foobar::from_orange(&mut fruit);
let c = Foobar::from_callback(|x| x*x);
混淆了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();
可以通过提供一些任意的类型参数来解决这个问题:
let a = Foobar::<()>::from_nowhere();
let b = Foobar::<()>::from_orange(&mut fruit);
let c = Foobar::<()>::from_callback(|x| x*x);
......这很丑陋。另一种解决问题的方法是将构造函数转换为自由函数,但这可能不太符合惯例。
问题是,我是否漏掉了什么?这个设计似乎有些缺陷。如何正确地设计此类型以仅使用一级泛型?
作为参考,我的编译器版本是:
$ rustc --version
rustc 1.1.0-dev (built 2015-04-26)