为什么在if let的else块中仍保留借贷?

为什么self.f2()以下代码中的调用使借阅检查器跳闸?else块不是在其他范围内吗?这是一个难题!


use std::str::Chars;


struct A;


impl A {

    fn f2(&mut self) {}


    fn f1(&mut self) -> Option<Chars> {

        None

    }


    fn f3(&mut self) {

        if let Some(x) = self.f1() {


        } else {

            self.f2()

        }

    }

}


fn main() {

    let mut a = A;

}

操场


error[E0499]: cannot borrow `*self` as mutable more than once at a time

  --> src/main.rs:16:13

   |

13 |         if let Some(x) = self.f1() {

   |                          ---- first mutable borrow occurs here

...

16 |             self.f2()

   |             ^^^^ second mutable borrow occurs here

17 |         }

   |         - first borrow ends here

自我借入的范围不是以self.f1()电话开始还是结束吗?一旦来自的呼叫f1()返回f1()不再使用self,因此借用检查器应该不会对第二个借用有任何问题。请注意以下代码也会失败...


// ...

if let Some(x) = self.f1() {

    self.f2()

}

// ...

操场


我认为这里的第二次借阅应该很好f1,f3并且不要self与同时使用f2。


白衣染霜花
浏览 487回答 3
3回答

当年话下

这很烦人,但是您可以通过引入内部作用域并稍微更改控制流来解决此问题:fn f3(&mut self) {&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; if let Some(x) = self.f1() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // ...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; self.f2()}正如评论中指出的那样,此方法无需使用大括号即可。这是因为ifor if...let表达式具有隐式范围,并且借用持续于该范围:fn f3(&mut self) {&nbsp; &nbsp; if let Some(x) = self.f1() {&nbsp; &nbsp; &nbsp; &nbsp; // ...&nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; }&nbsp; &nbsp; self.f2()}这是Sandeep Datta和mbrubeck之间的IRC聊天记录:mbrubeck: std:tr :: Chars包含对创建它的字符串的借用引用。完整类型名称为Chars<'a>。因此,f1(&mut self) -> Option<Chars>不作任何省略就f1(&'a mut self) -> Option<Chars<'a>>意味着self只要从中获得的返回值f1在范围内,就保持借用状态。Sandeep Datta:为避免出现此问题,我可以将'b用作自我,将'a用作字符吗?mbrubeck:如果您实际上是要从中返回某个对象的迭代器,则不会self。但是,如果您可以通过&self -> Chars(而不是&mut self -> Chars)创建函数,则可以解决此问题。
打开App,查看更多内容
随时随地看视频慕课网APP