IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    &\'a mut self is restrictive

    金庆发表于 2021-08-25 05:32:00
    love 0
    # &'a mut self is restrictive

    From https://github.com/pretzelhammer/rust-blog/blob/master/posts/common-rust-lifetime-misconceptions.md#5-if-it-compiles-then-my-lifetime-annotations-are-correct

    ```
    #[derive(Debug)]
    struct NumRef<'a>(&'a i32);

    impl<'a> NumRef<'a> {
        // my struct is generic over 'a so that means I need to annotate
        // my self parameters with 'a too, right? (answer: no, not right)
        fn some_method(&'a mut self) {}
    }

    fn main() {
        let mut num_ref = NumRef(&5);
        num_ref.some_method(); // mutably borrows num_ref for the rest of its lifetime
        num_ref.some_method(); // ❌
        println!("{:?}", num_ref); // ❌
    }
    ```

    If we have some struct generic over 'a we almost never want to write a method with a &'a mut self receiver. 
    What we're communicating to Rust is "this method will mutably borrow the struct for the entirety of the struct's lifetime". 
    In practice this means Rust's borrow checker will only allow at most one call to some_method 
    before the struct becomes permanently mutably borrowed and thus unusable. 
    The use-cases for this are extremely rare but the code above is very easy for confused beginners to write and it compiles. 
    The fix is to not add unnecessary explicit lifetime annotations and let Rust's lifetime elision rules handle it:

    ```
    #[derive(Debug)]
    struct NumRef<'a>(&'a i32);

    impl<'a> NumRef<'a> {
        // no more 'a on mut self
        fn some_method(&mut self) {}

        // above line desugars to
        fn some_method_desugared<'b>(&'b mut self){}
    }

    fn main() {
        let mut num_ref = NumRef(&5);
        num_ref.some_method();
        num_ref.some_method(); // ✅
        println!("{:?}", num_ref); // ✅
    }
    ```


    金庆 2021-08-25 13:32 发表评论


沪ICP备19023445号-2号
友情链接