使用结构存储对非Copy值的引用

时间:2018-10-09 10:12:33

标签: struct reference rust

我需要一个对象,该对象包含对流程子的引用,并使我能够在其上执行功能。

pub struct Shell {
    child: std::process::Child,
}

impl Shell {
    pub fn init() -> Shell {
        let mut cmd = std::process::Command::new("Command");
        let process = cmd.spawn();
        let new = Shell {
            child: process.unwrap(),
        };
        new
    }

    pub fn f1(mut self) {
        //do something with self
    }

    pub fn f2(mut self) {
        {
            let stdin = self.child.stdin.as_mut().unwrap();
        }
        let output = self.child.wait_with_output();
    }
}

fn main() {
    let mut shell = Shell::init();
    shell.f1();
    shell.f2();
}
error[E0382]: use of moved value: `shell`
  --> src/main.rs:28:5
   |
27 |     shell.f1();
   |     ----- value moved here
28 |     shell.f2();
   |     ^^^^^ value used here after move
   |
   = note: move occurs because `shell` has type `Shell`, which does not implement the `Copy` trait

>Try it

问题在于,当我初始化对象时,我只能在对象上调用一次函数,因为由于标准Rust行为,该值在第一次调用时被移动了。

一个简单的#[derive(Copy, Clone)]在这里不起作用,因为std::process::Child似乎没有实现Copy特质。有没有办法避免这种情况或将其包装成可复制的内容?

测试实现

使用可变引用作为函数参数时,最初的问题似乎已解决,但是,访问self.child不可能一次以上。

pub struct Shell {
    child: std::process::Child,
}

impl Shell {
    pub fn init() -> Shell {
        let mut cmd = std::process::Command::new("Command");
        let process = cmd.spawn();
        let new = Shell {
            child: process.unwrap(),
        };
        new
    }

    pub fn f1(&mut self) {
        //do something with self
    }

    pub fn f2(&mut self) {
        {
            let stdin = self.child.stdin.as_mut().unwrap();
        }
        let output = self.child.wait_with_output();
    }
}

fn main() {
    let mut shell = Shell::init();
    shell.f1();
    shell.f2();
}
error[E0507]: cannot move out of borrowed content
  --> src/main.rs:21:22
   |
21 |         let output = self.child.wait_with_output();
   |                      ^^^^ cannot move out of borrowed content

>Try it

有办法解决吗?

1 个答案:

答案 0 :(得分:0)

问题在于self.child必须消耗wait_with_output()。这就是为什么self不能通过引用而是通过值传递给f2的原因:

pub struct Shell {
    child: std::process::Child,
}

impl Shell {
    pub fn init() -> Shell {
        let mut cmd = std::process::Command::new("Command");
        let process = cmd.spawn();
        let new = Shell {
            child: process.unwrap(),
        };
        new
    }

    pub fn f1(&mut self) {
        //do something with self
    }

    pub fn f2(mut self) {
        {
            let stdin = self.child.stdin.as_mut().unwrap();
        }
        let output = self.child.wait_with_output();
    }
}

fn main() {
    let mut shell = Shell::init();
    shell.f1();
    shell.f2();
}

>Try it

但这意味着f2必须是访问self.child的最后一个函数。