这是对我的问题的一个可重复的简化:

struct Val<'a>(&'a str);

impl Val<'_> {
    fn get(&self) -> Option<&str> {
        Some(self.0)
    }
}

// Not used here, but this borrow needs to be mutable
fn test<'a>(param: &'a mut Val<'a>) -> Option<&'a str> {
    param.get()
}

fn main() {
    let s = String::from("hello");
    let mut v = Val(&s);
    
    while let Some(x) = test(&mut v) {
        println!("{x}");
    }
}

playground link

我得到了:

   |
17 |     while let Some(x) = test(&mut v) {
   |                              ^^^^^^
   |                              |
   |                              `v` was mutably borrowed here in the previous iteration of the loop
   |                              first borrow used here, in later iteration of loop

For more information about this error, try `rustc --explain E0499`.

首先,我try 更改borrow 的生存期,以指示它没有原始数据的生存期长,如下所示:

fn test<'a, 'b>(param: &'b mut Val<'a>) -> Option<&'a str> {
    param.get()
}

But then 我得到了:

   |
9  | fn test<'a, 'b>(param: &'b mut Val<'a>) -> Option<&'a str> {
   |         --  -- lifetime `'b` defined here
   |         |
   |         lifetime `'a` defined here
10 |     param.get()
   |     ^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
   |
   = help: consider adding the following bound: `'b: 'a`

添加建议的界限会让我回到前面的错误.

我选中了this related question,这表明这是borrow 判断器的限制,因此我try 将代码更改为:

fn main() {
    let s = String::from("hello");
    let mut v = Val(&s);
    
    loop {
        let x = test(&mut v);
        if let Some(y) = x {
            println!("{y}");
        }
    }
}

playground link

但我得到了相同的第一个错误.在我的用例中,test的行为或多或少类似于next from迭代器,因此我不能在同一迭代中调用它两次.

有没有办法:

  • 是否返回生存期为'a而不是fn test中的'b的数据?
  • 或者,对于单一的'a生命周期,使borrow 在迭代结束时被删除?

Edit:当翻译回我真正的问题时,我注意到这个例子并不能完全代表它,我仍然在使它工作方面有问题.我对示例here进行了一些更改,并在生命周期中进行了一些额外的更改以使其正常工作.现在它运行得很好.总而言之,test函数必须对get返回的值进行一些映射,在这个过程中,它返回的是生存期'b而不是'a.

推荐答案

固有函数Val::get()在返回值中具有错误的生命周期 .该函数返回内部值Val,因此返回值应该具有该内部值的生存期.由于lifetime elision,您的get()实现的签名相当于

fn get<'b>(&'b self) -> Option<&'b str>;

换句话说,在返回值的整个生命周期内总是borrow self,这是不必要的.borrow 值self的生存期与返回字符串的生存期完全无关.

您还需要像您已经try 过的那样,在test()年中将这两个生命周期分离.以下是完整的工作代码:

struct Val<'a>(&'a str);

impl<'a> Val<'a> {
    fn get(&self) -> Option<&'a str> {
        Some(self.0)
    }
}

fn test<'a, 'b>(param: &'b mut Val<'a>) -> Option<&'a str> {
    param.get()
}

fn main() {
    let s = String::from("hello");
    let mut v = Val(&s);

    while let Some(x) = test(&mut v) {
        println!("{x}");
    }
}

(为了清楚起见,我在test()中添加了'b.您也可以简单地省略它,并使用&mut Val<'a>作为param的类型,这也是由于终生省略.)

Rust相关问答推荐

阻止websocket中断的中断中断的终端(操作系统错误4)

Rust中的相互递归特性与默认实现

值为可变对象的不可变HashMap

如何使用syn插入 comments ?

当一个箱子有自己的依赖关系时,两个人如何克服S每箱1库+n箱的限制?

如何为rust trait边界指定多种可能性

在rust sqlx中使用ilike和push bind

如果包名称与bin名称相同,并且main.ars位于工作区的同一 crate 中,则无法添加对lib.ars的依赖

`RwLockWriteGuard_,T`不实现T实现的特征

为什么`AlternateScreen`在读取输入键时需要按Enter键?

为什么`tokio::main`可以直接使用而不需要任何导入?

为什么在 Allocator API 中 allocate() 使用 `[u8]` 而 deallocate 使用 `u8` ?

提取指向特征函数的原始指针

当没有实际结果时,如何在 Rust 中强制执行错误处理?

Rust 中的内存管理

为什么要这样编译?

n 个范围的笛卡尔积

如何在 use_effect_with_deps 中设置监听器内的状态?

为什么 Rust 编译器在移动不可变值时执行复制?

类型组的通用枚举