代码之家  ›  专栏  ›  技术社区  ›  ajp

为什么helper访问器方法会导致生存期错误(与内联访问器相比)?

  •  0
  • ajp  · 技术社区  · 3 年前

    游乐场连接 https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f9217c8f4c6fe708fec852c9515d9fd6

    version1() 不起作用, version2() 确实如此,即使它应该是等效的(只是内联 get_x_mut )

    在我的实际代码中, get_x_mut 正在返回一个嵌套字段,因此使用访问器抽象出访问权限会非常方便。

    我也很困惑为什么循环迭代之间会发生冲突——我没有存储任何引用。

    struct Bar<'a> {
        foo: Option<&'a Foo<'a>>
    }
    
    impl<'a> Bar<'a> {
        fn bar(&mut self) {}
    }
    
    struct Foo<'a> {
        x: Bar<'a>,
        y: Option<Bar<'a>>
    }
    
    impl<'a> Foo<'a> {
        fn get_x_mut(&'a mut self) -> &'a mut Bar {
            &mut self.x
        }
        
        fn get_y(&self) -> &Option<Bar> {
            &self.y
        }
    
        fn version1(&'a mut self) {
            loop {
                if let Some(y) = self.get_y() {
                    let x = self.get_x_mut();
                    x.bar();
                }
            }
        }
        
        fn version2(&'a mut self) {
            loop {
                if let Some(y) = self.get_y() {
                    let x = &mut self.x;
                    x.bar();
                }
            }
        }
    }
    

    错误消息为

    error[E0502]: cannot borrow `*self` as immutable because it is also borrowed as mutable
      --> src/lib.rs:25:30
       |
    14 | impl<'a> Foo<'a> {
       |      -- lifetime `'a` defined here
    ...
    25 |             if let Some(y) = self.get_y() {
       |                              ^^^^^^^^^^^^ immutable borrow occurs here
    26 |                 let x = self.get_x_mut();
       |                         ----------------
       |                         |
       |                         mutable borrow occurs here
       |                         argument requires that `*self` is borrowed for `'a`
    
    error[E0499]: cannot borrow `*self` as mutable more than once at a time
      --> src/lib.rs:26:25
       |
    14 | impl<'a> Foo<'a> {
       |      -- lifetime `'a` defined here
    ...
    26 |                 let x = self.get_x_mut();
       |                         ^^^^^^^^^^^^^^^^
       |                         |
       |                         `*self` was mutably borrowed here in the previous iteration of the loop
       |                         argument requires that `*self` is borrowed for `'a`
    
    1 回复  |  直到 3 年前
        1
  •  0
  •   Chayim Friedman    3 年前

    因为你指定的寿命是错误的。

    这个:

    fn get_x_mut(&'a mut self) -> &'a mut Bar {
        &mut self.x
    }
    

    应该是这样的:

    fn get_x_mut(&mut self) -> &mut Bar<'a> {
        &mut self.x
    }
    

    这相当于:

    fn get_x_mut<'b>(&'b mut self) -> &'b mut Bar<'a> {
        &mut self.x
    }
    

    然而,整个事情一开始就错了。您正试图创建 自引用结构 ,这在Rust中是不允许的。你现在可能已经成功了,但最终你会失败的。看见 Why can't I store a value and a reference to that value in the same struct?

    推荐文章