Использование структуры для хранения ссылки на не копируемое значение - PullRequest
0 голосов
/ 09 октября 2018

Мне нужен объект, который содержит ссылку на дочерний процесс и позволяет мне выполнять функции над ним.

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

> Попробуйте

Проблема в том, что когда я инициализирую свой объект, я могу вызывать функции для объекта только один раз, потому что значение перемещается при первом вызове из-за стандартного поведения 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

> Попробуйте

Есть ли способ решить эту проблему?

1 Ответ

0 голосов
/ 09 октября 2018

Проблема в том, что 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();
}

> Попробуйте

Однако это означает, что f2 должна быть последней функцией, которая обращается к self.child.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...