具有特征字段的结构,但可选
A struct with a trait field, but optional
假设我有一个结构,其实现写入 某处,即实现 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
我真的不确定如何解释这些错误消息,令人惊讶的是,我只是在没有真正理解的情况下随意散布 &
s 和 mut
s 并没有真正取得任何进展!
(顺便说一句,我不确定这是否是解决此问题的“好”方法?我对解决此问题的完全不同的方法持开放态度,这基本上是有选择地传递一些东西给写入一个结构,但没有结构拥有它。我读到 Box
类型可能也相关?)
如您所知,基于您已经将 &mut
用于 out
。使用 as_ref()
is that it returns an immutable reference. Instead you need to use as_mut()
.
的问题
pub fn print_number(&mut self, i: isize) {
if self.out.is_some() {
writeln!(self.out.as_mut().unwrap(), "The number is {}", i).unwrap()
}
}
或者,您也可以简化它并使用 if let
:
更地道地表达它
pub fn print_number(&mut self, i: isize) {
if let Some(out) = &mut self.out {
writeln!(out, "The number is {}", i).unwrap()
}
}
我还建议您 return io::Result
并让调用者处理任何潜在的错误,而不是解包。
pub fn print_number(&mut self, i: isize) -> std::io::Result<()> {
if let Some(out) = &mut self.out {
writeln!(out, "The number is {}", i)?;
}
Ok(())
}
您还可以简化路径,例如std::io::Write
和 std::io::Result<()>
,通过使用 use declaration 导入它们,例如use std::io::{self, Write};
然后将它们更改为 Write
和 io::Result<()>
.
假设我有一个结构,其实现写入 某处,即实现 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
我真的不确定如何解释这些错误消息,令人惊讶的是,我只是在没有真正理解的情况下随意散布 &
s 和 mut
s 并没有真正取得任何进展!
(顺便说一句,我不确定这是否是解决此问题的“好”方法?我对解决此问题的完全不同的方法持开放态度,这基本上是有选择地传递一些东西给写入一个结构,但没有结构拥有它。我读到 Box
类型可能也相关?)
如您所知,基于您已经将 &mut
用于 out
。使用 as_ref()
is that it returns an immutable reference. Instead you need to use as_mut()
.
pub fn print_number(&mut self, i: isize) {
if self.out.is_some() {
writeln!(self.out.as_mut().unwrap(), "The number is {}", i).unwrap()
}
}
或者,您也可以简化它并使用 if let
:
pub fn print_number(&mut self, i: isize) {
if let Some(out) = &mut self.out {
writeln!(out, "The number is {}", i).unwrap()
}
}
我还建议您 return io::Result
并让调用者处理任何潜在的错误,而不是解包。
pub fn print_number(&mut self, i: isize) -> std::io::Result<()> {
if let Some(out) = &mut self.out {
writeln!(out, "The number is {}", i)?;
}
Ok(())
}
您还可以简化路径,例如std::io::Write
和 std::io::Result<()>
,通过使用 use declaration 导入它们,例如use std::io::{self, Write};
然后将它们更改为 Write
和 io::Result<()>
.