Скажем, у меня есть структура, реализация которой записывает где-то, то есть во что-то, что реализует черту std::io::Write
. Однако я не хочу, чтобы структура владела этим. Следующий код работает:
fn main() {
let mut out = std::io::stdout();
let mut foo = Foo::new(&mut out);
foo.print_number(2);
}
struct Foo<'a> {
out: &'a mut dyn std::io::Write
}
impl<'a> Foo<'a> {
pub fn new(out: &'a mut dyn std::io::Write) -> Self {
Self {
out
}
}
pub fn print_number(&mut self, i: isize) {
writeln!(self.out, "The number is {}", i).unwrap()
}
}
Но теперь эту функцию записи следует сделать необязательной. Я думал, что это звучит достаточно просто, но теперь следующее не компилируется:
fn main() {
let mut out = std::io::stdout();
let mut foo = Foo::new(Some(&mut out));
foo.print_number(2);
}
struct Foo<'a> {
out: Option<&'a mut dyn std::io::Write>
}
impl<'a> Foo<'a> {
pub fn new(out: Option<&'a mut dyn std::io::Write>) -> Self {
Self {
out
}
}
pub fn print_number(&mut self, i: isize) {
if self.out.is_some() {
writeln!(self.out.unwrap(), "The number is {}", i).unwrap()
}
}
}
из-за:
error[E0507]: cannot move out of `self.out` which is behind a mutable reference
--> src/main.rs:20:26
|
20 | writeln!(self.out.unwrap(), "The number is {}", i).unwrap()
| ^^^^^^^^
| |
| move occurs because `self.out` has type `Option<&mut dyn std::io::Write>`, which does not implement the `Copy` trait
| help: consider borrowing the `Option`'s content: `self.out.as_ref()`
что я не знаю, как интерпретировать.
Я попытался последовать предложению, изменив соответствующую строку на:
writeln!(self.out.as_ref().unwrap(), "The number is {}", i).unwrap()
но потом я получаю
error[E0596]: cannot borrow data in a `&` reference as mutable
--> src/main.rs:20:26
|
20 | writeln!(self.out.as_ref().unwrap(), "The number is {}", i).unwrap()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
Я действительно не уверен, как интерпретировать эти сообщения об ошибках, и, что удивительно, я ничего не добился, просто разбрасывая &
и mut
в случайных местах, не понимая ничего!
(Кстати, я не уверен, что это хороший способ сделать это в любом случае? Я открыт для совершенно разных подходов к решению этой проблемы, которые в основном заключаются в необязательной передаче чего-то для записи в структуру, но без структуры, владеющей им. Я читал о типе Box
, который также может иметь значение?)
is_some()
обычно не то, что вам нужно. Обычно вы хотите знать, чтоSome
и хотят получить доступ к внутреннему значению, а сопоставление с образцом (черезmatch
илиif let
) обеспечивает и то, и другое. - person kmdreko   schedule 05.01.2021