请考虑以下代码:

struct Foo<'a> {
    borrowed: &'a u8,
    owned_one: Vec<u8>,
    owned_two: Vec<u8>,
    output: usize
}

impl<'a> Foo<'a> {
    fn do_stuff(&mut self) {
        self.output = self.owned_one.len();
        let zipped = self.owned_one.iter().zip(self.owned_two.iter());
        Self::subroutine(&zipped);
    }
    
    fn subroutine<Arg: Iterator<Item=(&'a u8, &'a u8)>>(_zipped: &Arg) {}
}

fn main() {
    let num = 0u8;
    let mut foo = Foo {
        borrowed: &num,
        owned_one: vec![0],
        owned_two: vec![1],
        output: 0
    };
    foo.do_stuff();
    let _out = &foo.output;
}

(playground link)

它不能编译,并产生以下错误:

error: lifetime may not live long enough
  --> src/lib.rs:12:9
   |
8  | impl<'a> Foo<'a> {
   |      -- lifetime `'a` defined here
9  |     fn do_stuff(&mut self) {
   |                 - let's call the lifetime of this reference `'1`
...
12 |         Self::subroutine(&zipped);
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'a`

我不理解fully的抱怨--当然self总是会被分配给我们正在教授的班级的生命周期?--但我能理解zip()的两个论点需要持续相同的时间.所以我把do_stuff改成了&'a mut self.

struct Foo<'a> {
    borrowed: &'a u8,
    owned_one: Vec<u8>,
    owned_two: Vec<u8>,
    output: usize
}

impl<'a> Foo<'a> {
    fn do_stuff(&'a mut self) {
        self.output = self.owned_one.len();
        let zipped = self.owned_one.iter().zip(self.owned_two.iter());
        Self::subroutine(&zipped);
    }
    
    fn subroutine<Arg: Iterator<Item=(&'a u8, &'a u8)>>(_zipped: &Arg) {}
}

fn main() {
    let num = 0u8;
    let mut foo = Foo {
        borrowed: &num,
        owned_one: vec![0],
        owned_two: vec![1],
        output: 0
    };
    foo.do_stuff();
    let _out = &foo.output;
}

但是,现在编译失败,出现以下错误:

error[E0502]: cannot borrow `foo.output` as immutable because it is also borrowed as mutable
  --> src/lib.rs:27:16
   |
26 |     foo.do_stuff();
   |     -------------- mutable borrow occurs here
27 |     let _out = &foo.output;
   |                ^^^^^^^^^^^
   |                |
   |                immutable borrow occurs here
   |                mutable borrow later used here

为什么在do_stuff的参数列表中指定self的生存期意味着我突然不能在以后接受对foo的不可变引用;我能做些什么呢?

推荐答案

在这种背景下写fn do_stuff(&'a mut self)意味着这个借的self 的一生,必须一生只要这个self 有借的borrowed.这通常不是你想要的.

你的错误在这里是fn subroutine<Arg: Iterator<Item=(&'a u8, &'a u8)>>(_zipped: &Arg) {}.想一想你的声明的词义.您的方法不返回任何内容,但需要"父"生存期?没有理由这样做.简单的解决方案就是为你的物品引入一个新的生命周期.比如fn subroutine<'i, Arg: Iterator<Item=(&'i u8, &'i u8)>>(_zipped: &Arg) {}.除非您的函数返回指向'a的链接,否则此处不应包含父对象的生存期.

此外,最好接受IntoIterator,它更一般,没有理由通过引用来接受它,最后,当你有如此复杂的一般更好地使用where,真的,如果你想变得书生气,你需要两个一生:

fn subroutine<'i, 'j, Arg>(_zipped: Arg)
where
    Arg: IntoIterator<Item = (&'i u8, &'j u8)>,
{
}

Rust相关问答推荐

如何在不安全的代码中初始化枚举 struct

如何在tauri—leptos应用程序中监听后端值的变化?""

如何导出 rust 色二进制文件中的符号

为昂贵的for循环制作筛子

更合理的方法来设计样条线函数器?

了解Rust';s特征对象和不同函数签名中的生存期注释

在 Rust 中,为什么 10 个字符的字符串的 size_of_val() 返回 24 个字节?

在描述棋盘时如何最好地使用特征与枚举

Rust:为什么 Pin 必须持有指针?

Rust中如何实现一个与Sized相反的负特性(Unsized)

我可以在 Rust 中 serde struct camel_case 和 deserde PascalCase

特征中定义的类型与一般定义的类型之间的区别

SDL2 没有在终端键上触发?

Rust 中函数的类型同义词

我如何将特征作为 struct 的拥有字段?

如何在 nom 中构建负前瞻解析器?

为什么分配对变量的引用使我无法返回它

Rust 内联 asm 中的向量寄存器:不能将 `Simd` 类型的值用于内联汇编

类型组的通用枚举

为什么 Rust 标准库同时为 Thing 和 &Thing 实现特征?