rust - 如何限制关联类型接受任何引用生命周期?

标签 rust borrow-checker

我有一个简单的特征,它有一个接受关联类型的函数。

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/

相关文章:

multithreading - Rust 相当于 Intel 的 tbb::concurrent_queue 吗?

rust - 如何为我不拥有的类型实现我不拥有的特征?

rust - 在匹配语句中重用匹配变量

loops - 当存在可变引用时传递不可变引用

Rust - 单行内的条件变异

rust - 访问枚举变量字段的正确方法,该字段本身就是结构的字段

rust - 如何构建一个树结构,其中节点包含对包含树结构的字段的引用

vector - 在Vec中查找一对元素

rust - 引用上的Rust调用方法

rust - 跳过在Rust中如何工作?