Reference to unwrapped property fails: use of partially moved value: `self`

天大地大妈咪最大 提交于 2020-01-05 07:43:39

问题


I try to send an unwrapped string reference to a static method implemented for a struct. Here is a simplified code:

fn main() {
    let a = A {p: Some("p".to_string())};
    a.a();
}

struct A {
    p: Option<String>
}

impl A {
    fn a(self) -> Self {
        Self::b(&self.p.unwrap());
        self
    }
    fn b(b: &str) {
        print!("b: {}", b)
    }
}

It fails:

error[E0382]: use of partially moved value: `self`
  --> src/main.rs:14:13
   |
13 |             Self::b(&self.p.unwrap());
   |                      ------ value moved here
14 |             self
   |             ^^^^ value used here after move
   |
   = note: move occurs because `self.p` has type `std::option::Option<std::string::String>`, which does not implement the `Copy` trait

I think implementing the Copy trait is not a solution. How can I unwrap p and pass it as a &str to b in that context?

I changed my code as suggested in Can't borrow File from &mut self (error msg: cannot move out of borrowed content):

fn main() {
    let a = A {p: Some("p".to_string())};
    a.a();
}

struct A {
    p: Option<String>
}

impl A {
    fn a(self) -> Self {
        let c = self.p.as_ref().unwrap();
        Self::b(&c);
        self
    }
    fn b(b: &str) {
        print!("b: {}", b)
    }
}

Which results in a different error:

error[E0505]: cannot move out of `self` because it is borrowed
  --> src/main.rs:15:13
   |
13 |             let c = self.p.as_ref().unwrap();
   |                     ------ borrow of `self.p` occurs here
14 |             Self::b(&c);
15 |             self
   |             ^^^^ move out of `self` occurs here

回答1:


As discussed in Can't borrow File from &mut self (error msg: cannot move out of borrowed content), you can't call unwrap on a borrowed value because unwrap takes ownership of the value.

Changing to as_ref borrows from the value self. You are not allowed to move a value (which includes returning that value) while any references to it are outstanding. That means you need to constrain the life of the borrow to end before the value needs to be moved:

fn a(self) -> Self {
    {
        let c = self.p.as_ref().unwrap();
        Self::b(c);
    }
    self
}

It may be an artifact of your example, but the code is pretty strange. I'd have written it as

impl A {
    fn a(self) -> Self {
        self.b();
        self
    }

    fn b(&self) {
        print!("b: {}", self.p.as_ref().unwrap())
    }
}

Or

impl A {
    fn a(&self) {
        print!("a: {}", self.p.as_ref().unwrap())
    }
}


来源:https://stackoverflow.com/questions/40615054/reference-to-unwrapped-property-fails-use-of-partially-moved-value-self

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!