我有一个简单的特征,它有一个接受关联类型的函数。
pub trait Pipe {
type Item;
fn push(&mut self, value: Self::Item);
}
现在我想用 Pipe
做一些事情,它接受引用而不是拥有的值。pub fn do_something_ref<T>(trait_inst: T)
where
T: Pipe<Item = &usize>
{
let val: usize = 5;
trait_inst.push(&val);
}
引用的存活时间不会超过调用者上下文的生命周期。也许 Pipe 克隆了这个值。也许它只会打印它。
但是不允许存储它,因为这会违反调用者上下文生命周期。
但是上面的代码给出了一个错误:
error[E0637]: `&` without an explicit lifetime name cannot be used here
。Playground Link
我怎样才能使这项工作?
这是我的尝试。
所以,似乎 higher ranked trait bounds (HRTB) 在这里很有用。如果我可以说“所有可能的
P: Pipe<Item = &'a>
的 'a
”,那么这意味着 Pipe 将接受非常短暂的引用。pub fn do_something_ref<T>(trait_inst: T)
where
for <'a> T: Pipe<Item = &'a usize>
{
let val: usize = 5;
trait_inst.push(&val);
}
我认为这应该有效,但它也不能编译: error[E0582]: binding for associated type `Item` references lifetime `'a`, which does not appear in the trait input types
。Playground Link
该错误是错误吗?
可能是 https://github.com/rust-lang/rust/issues/49601 吗?
所以看起来这个错误只是因为
'a
不在编译器认为对 for<'a>
有效的地方。所以我试图通过添加一个未使用的生命周期参数或辅助特性来找到一些解决方法,虽然我发现 some solutions which initially compiled ,但当你尝试使用它们时,没有一个真正起作用。我怎样才能让它按照我想要的方式工作?谢谢!
Old discussion on internals: "Opposite of &’static"
最佳答案
如果不坚持引用是 push()
的属性,您可以通过修改特征来解决问题(问题不清楚是否允许):
pub trait Pipe<'a> {
type Item;
fn push(&mut self, value: Self::Item);
}
pub fn do_something_ref<T>(mut trait_inst: T)
where
T: for<'a> Pipe<'a, Item = &'a usize>,
{
let val: usize = 5;
trait_inst.push(&val);
}
...它可以实现( playground )。如果不修改特征,就像另一个答案所说的那样,没有什么可以阻止
push()
从坚持值(value)。 (类似的问题会阻止流迭代器工作——除非你不能“修复”迭代器,因为修复会阻止常规迭代器工作。)
关于rust - 如何限制关联类型接受任何引用生命周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64885074/