Borrowing references to attributes in a struct

前端 未结 2 1228
滥情空心
滥情空心 2020-11-28 16:11

It seems that if you borrow a reference to a struct field, the whole struct is considered borrowed. I\'ve managed to isolate and example of what I want to do. I just want to

2条回答
  •  离开以前
    2020-11-28 16:46

    Expanding a bit on Levans' answer

    Move the code which needs to access both attribute inside a method of B

    That might look like this at a first pass:

    impl B {
        fn do_thing(&mut self) {
            self.j = self.a.foo()
        }
    }
    

    However, this hard-codes the call to foo. You could also accept a closure to allow this to be more flexible:

    impl B {
        fn update_j_with_a(&mut self, f: F)
        where
            F: FnOnce(&mut A) -> i32,
        {
            self.j = f(&mut self.a)
        }
    }
    
    // ...
    
    b.update_j_with_a(|a| a.foo())
    

    Separate your two fields into two different structs

    This is also applicable when you have borrowed two disjoint subsets of attributes. For example:

    struct A {
        description: String,
        name: String,
        age: u8,
        money: i32,
    }
    
    impl A {
        fn update_description(&mut self) {
            let description = &mut self.description;
            *description = self.build_description()
            // cannot borrow `*self` as immutable because `self.description` is also borrowed as mutable
        }
    
        fn build_description(&self) -> String {
            format!(
                "{} is {} years old and has {} money",
                self.name,
                self.age,
                self.money
            )
        }
    }
    
    fn main() {}
    

    Can be changed into

    struct A {
        description: String,
        info: Info,
    }
    
    struct Info {
        name: String,
        age: u8,
        money: i32,
    }
    
    impl A {
        fn update_description(&mut self) {
            let description = &mut self.description;
            *description = self.info.build_description()
        }
    }
    
    impl Info {
        fn build_description(&self) -> String {
            format!(
                "{} is {} years old and has {} money",
                self.name,
                self.age,
                self.money
            )
        }
    }
    
    fn main() {}
    

    You can combine these two steps (and I'd say that it's better practice) and move the method onto the inner struct.

提交回复
热议问题