想象一下一些事件源,它产生表示为枚举的事件.当然,为了获得最佳效率,此生产者是零拷贝,即它返回对其内部缓冲区的引用:
enum Variant<'a> {
Nothing,
SomeInt(u64),
SomeBytes(&'a [u8])
}
impl Producer {
fn next(&'a mut self) -> Variant<'a> { ... }
}
Run Code Online (Sandbox Code Playgroud)
这对于不需要前瞻或回溯的消费者来说非常好,但有时需要保存一些事件序列.因此,我们的Variant类型变为通用:
enum Variant<BytesT> {
Nothing,
SomeInt(u64),
SomeBytes(BytesT)
}
type OwnedVariant = Variant<Vec<u8>>;
type BorrowedVariant<'a> = Variant<&'a [u8]>;
Run Code Online (Sandbox Code Playgroud)
在这里,我们最终得到两种具有"所有者 - 参考"关系的类型,它类似于对Vec<T>- &[T],String- &str.文档建议内置特征Borrow,ToOwned除了微妙的细微差别外,它提供了所需的内容:
trait Borrow<Borrowed: ?Sized> {
fn borrow(&self) -> &Borrowed;
// this: -----------^
}
pub trait ToOwned {
type Owned: Borrow<Self>;
fn to_owned(&self) -> Self::Owned;
} …Run Code Online (Sandbox Code Playgroud) 我正在为C库编写一个Rust绑定.它实现了一个可以从不同源实体构造的实体,可能在内部保存了一些引用.我希望Rust类型强制执行安全的所有权策略,因此包装器结构是通用的,由存储的引用的类型参数化.
struct Foobar<T> {
origin: T,
}
Run Code Online (Sandbox Code Playgroud)
然后我为我的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 }
}
}
Run Code Online (Sandbox Code Playgroud)
这就出现了问题:结构和构造函数都是独立参数化的.虽然可以从其参数推断构造函数类型参数,但构造函数中不使用struct type参数,也无法推断它.因此,调用构造函数的天真方式
let a = Foobar::from_nowhere();
let b = Foobar::from_orange(&mut fruit);
let c = Foobar::from_callback(|x| x*x);
Run Code Online (Sandbox Code Playgroud)
混淆rustc:
rustgen.rs:43:13: 43:33 error: unable …Run Code Online (Sandbox Code Playgroud)