Заимствование перемещенного значения: `stdout`

Я создал поле stdout в своей структуре TermWriter, потому что хочу иметь возможность использовать внешний стандартный вывод (например, из ящика Termion), а также фиктивный стандартный вывод для тестов (также внешний метод cursor_pos() и фиктивный для тестов ).

pub struct TermWriter<W: Write> {
    pub input: String,
    cursor_pos: Position,
    stdout: W,
}

impl<W: Write> TermWriter<W> {
    pub fn new(input: String, stdout: W) -> Self {
        Self {
            input,
            cursor_pos: Position { x: 1, y: 2 },
            stdout,
        }
    }

    pub fn right(&mut self) -> Result<(), InputError> {
        if self.cursor_pos.x <= self.input.len() as u16 {
            write!(self.stdout, "{}", termion::cursor::Right(1))?;

            let cursor_pos = self.stdout.cursor_pos()?;

            self.cursor_pos.x = cursor_pos.0;
        }

        Ok(())
    }
}

Таким образом, метод TermWriter new() принимает стандартный вывод в качестве параметра. Однако здесь есть проблема:

pub fn get_input(
    input_keys: impl Iterator<Item = Result<Key, std::io::Error>>,
    stdout: &mut impl Write,
) -> Result<Input, InputError> {
    let input = String::new();
    let mut term_writer = TermWriter::new(input, stdout);

    for key in input_keys {
        match key.unwrap() {
            Key::Right => term_writer.right()?,
            _ => {}
        }

        stdout.flush().unwrap();
    }

    let input = term_writer.input.trim().to_owned();

    Ok(Input::Text(input))
}

stdout был перемещен сюда: TermWriter::new(input, stdout), поэтому stdout.flush().unwrap(); заимствует перемещенное значение.

Как предотвратить эту проблему перемещения стоимости/заимствования?

Попробуйте TermWriter::new(input, &mut *stdout);

PitaJ 30.03.2023 19:23

@PitaJ Спасибо за предложение, но я понимаю cannot borrow `stdout` as mutable more than once at a time.

alexchenco 30.03.2023 19:25
term_writer.stdout.flush().unwrap()?
BallpointBen 30.03.2023 19:51
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
0
3
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

stdout доступен из вашего вновь созданного term_writer, так что это должно работать (то же самое, что вы делаете для input):

term_writer.stdout.flush().unwrap()

Другое дело, что вместо Write следует брать &mut Write, так как любой &mut Write также реализует Write.

pub fn get_input(
    ...
    stdout: impl Write,
)

Спасибо! Такое простое решение. Один вопрос: Итак, здесь я делаю term_writer.stdout.flush().unwrap(), но везде я делаю stdout.flush(). Означает ли это, что у меня здесь проблема с дизайном?

alexchenco 31.03.2023 15:14

@alexchenco ты имеешь в виду отсутствие term_writer или отсутствие unwrap?

drewtato 31.03.2023 21:07

Я имею в виду отсутствие term_writer.

alexchenco 03.04.2023 17:17

@alexchenco Пока вы не создаете несколько stdout, компилируется только один из них. Так что просто используйте то, что работает.

drewtato 03.04.2023 21:43

Другие вопросы по теме