rust - 如何指定生命周期以使本地引用值与传入引用不同?

标签 rust lifetime

我正在创建一个局部结构 (second),其中包含对局部变量 (wrapper) 的引用。反过来,这个局部变量引用了更长的生命周期 ('a)。我如何向编译器表明局部变量的生命周期不需要与更大的生命周期一样长?

此问题由以下代码 ( playground ) 重现:

#![allow(dead_code)]
use std::marker::PhantomData;

trait Abc {}

struct ImplAbc;
impl Abc for ImplAbc {}

struct WrappingAbc<'a, A> {
    value: &'a A,
}
impl<'a, A: Abc> Abc for WrappingAbc<'a, A> {}
impl<'a, A: Abc> WrappingAbc<'a, A> {
    fn new(value: &'a A) -> Self {
        WrappingAbc { value }
    }
}

struct AnotherWrapper<'a, K, A, S> {
    value: &'a A,
    other: usize,
    phantom_data: PhantomData<(K, S)>,
}
impl<'a, A: Abc, S: Strategy<KindOne, A>> AnotherWrapper<'a, KindOne, A, S> {
    fn new(value: &'a A) -> Self {
        AnotherWrapper {
            value,
            other: 0,
            phantom_data: PhantomData,
        }
    }
}
impl<'a, 'b, A: Abc, S: Strategy<KindTwo, WrappingAbc<'b, A>>>
    AnotherWrapper<'a, KindTwo, WrappingAbc<'b, A>, S>
{
    fn replace_value<SOther: Strategy<KindOne, A>>(
        old: AnotherWrapper<KindOne, A, SOther>,
        newvalue: &'a WrappingAbc<'b, A>,
    ) -> Self {
        AnotherWrapper {
            value: newvalue,
            other: old.other,
            phantom_data: PhantomData,
        }
    }
}
trait Kind {}
struct KindOne;
impl Kind for KindOne {}
struct KindTwo;
impl Kind for KindTwo {}

trait Strategy<K: Kind, A: Abc>: Sized {}
struct StrategyImpl;
impl<K: Kind, A: Abc> Strategy<K, A> for StrategyImpl {}

fn f<'a, A: Abc, SOne: Strategy<KindOne, A>, STwo: Strategy<KindTwo, WrappingAbc<'a, A>>>(
    x: &'a A,
) {
    let first = AnotherWrapper::<KindOne, A, SOne>::new(x);
    let wrapper = WrappingAbc::new(x);
    let second = AnotherWrapper::<KindTwo, WrappingAbc<A>, STwo>::replace_value(first, &wrapper);
    move_away(second);
}

fn move_away<'a, A: Abc, S: Strategy<KindTwo, WrappingAbc<'a, A>>>(
    _argument: AnotherWrapper<'a, KindTwo, WrappingAbc<'a, A>, S>,
) {
}
error[E0597]: `wrapper` does not live long enough
  --> src/lib.rs:62:88
   |
57 | fn f<'a, A: Abc, SOne: Strategy<KindOne, A>, STwo: Strategy<KindTwo, WrappingAbc<'a, A>>>(
   |      -- lifetime `'a` defined here
...
62 |     let second = AnotherWrapper::<KindTwo, WrappingAbc<A>, STwo>::replace_value(first, &wrapper);
   |                  ----------------------------------------------------------------------^^^^^^^^-
   |                  |                                                                     |
   |                  |                                                                     borrowed value does not live long enough
   |                  argument requires that `wrapper` is borrowed for `'a`
63 |     move_away(second);
64 | }
   | - `wrapper` dropped here while still borrowed

如果 second 已移动,我如何更改生命周期定义,使得 wrapper 不需要与 'a 一样长无论如何之后?我怀疑这与 move_away 的定义有关,因为当我将该行修改为此 (playground) 时:

fn move_away<'a, A: Abc, S: Strategy<KindTwo, A>>(_argument: AnotherWrapper<'a, KindTwo, A, S>) {}

代码编译。

最佳答案

move_away的定义改成如下解决编译错误:

fn move_away<'a, 'b, A: Abc, S: Strategy<KindTwo, WrappingAbc<'b, A>>>(
    _argument: AnotherWrapper<'a, KindTwo, WrappingAbc<'b, A>, S>
) {}

引入生命周期 'b 消除了内部 WrappingAbc 的生命周期与 'a 指定的一样长的要求父函数。

关于rust - 如何指定生命周期以使本地引用值与传入引用不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55573859/

相关文章:

opengl - 如何使用 gstreamer crates 从 BufferRef 中提取 GL 纹理 ID?

rust - 为什么需要使用加号运算符 (Iterator<Item = &Foo> + 'a) 为特征添加生命周期?

multithreading - 如何将对堆栈变量的引用传递给线程?

Rust 包使用不稳定库功能 'iter_nth_back'

rust - 为什么在函数返回时从 `HashMap::get`借用还没有结束?

closures - 如何将变量移出闭包?

rust - 借用检查器没有意识到 `clear` 丢弃了对局部变量的引用

iterator - 尝试实现迭代器: cannot infer an appropriate lifetime due to conflicting requirements

rust - 如何从 HashSet 中形成一个切片?

vector - 是否可以使用迭代器将向量分成 10 个一组?