对解包属性的引用失败:使用部分移动的值:`self`

rap*_*2-h 2 structure rust

我尝试将解包的字符串引用发送到为结构实现的静态方法。这是一个简化的代码:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

它失败:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为实施Copy特征不是解决方案。在那种情况下,我如何解包p并将其作为&strto传递b

我按照无法从 &mut self 借用文件中的建议更改了我的代码(错误消息:无法移出借用的内容)

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

这会导致不同的错误:

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
Run Code Online (Sandbox Code Playgroud)

She*_*ter 5

正如无法从 &mut self (error msg: cannot move out of Bored content) 中借用文件中所讨论的那样,您不能调用unwrap借用的值,因为unwrap它拥有该值的所有权。

更改为as_ref从值借用self。当任何对它的引用未完成时,您不得移动值(包括返回该值)。这意味着您需要在需要移动值之前将借用的生命周期限制为结束:

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

它可能是您示例的工件,但代码很奇怪。我会把它写成

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

    fn b(&self) {
        print!("b: {}", self.p.as_ref().unwrap())
    }
}
Run Code Online (Sandbox Code Playgroud)

或者

impl A {
    fn a(&self) {
        print!("a: {}", self.p.as_ref().unwrap())
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为将所有内容放在一行中可能更容易,例如 [this](https://play.rust-lang.org/?gist=d0e5c2a66513613d5136deab406793d1&amp;version=stable&amp;backtrace=0) (`Self::b(self.p .as_ref().unwrap())`) 以避免相当丑陋的块。 (2认同)