Struct 带有特征字段的结构,但可选

Struct 带有特征字段的结构,但可选,struct,rust,ownership,trait-objects,Struct,Rust,Ownership,Trait Objects,假设我有一个结构,它的实现写在某处,即实现std::io::Writetrait的东西。但是,我不希望结构拥有这个。以下代码起作用: 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 }

假设我有一个结构,它的实现写在某处,即实现
std::io::Write
trait的东西。但是,我不希望结构拥有这个。以下代码起作用:

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()
    }
}
但是我得到了

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随意地洒在一些地方,并没有取得任何进展


(顺便说一句,我不确定这是否是一种“好”的解决方法?我对解决这个问题的完全不同的方法持开放态度,基本上是有选择地将要写入的内容传递到结构中,但结构不拥有它。我读到了关于
类型的文章,这可能也相关?)

如您所知,基于您已经为
out
使用
&mut
。使用的问题是它返回一个不可变的引用。相反,您需要使用

pub fn打印编号(&mut self,i:isize){
如果self.out.is_some(){
writeln!(self.out.as_mut().unwrap(),“数字是{}”,i).unwrap()
}
}
或者,您也可以简化此操作,并使用以下方法更惯用地表达:

pub fn打印编号(&mut self,i:isize){
如果释放一些(out)=&mut self.out{
writeln!(out,“数字是{}”,i).unwrap()
}
}

我还建议您返回并让调用者处理任何潜在的错误,而不是展开

pub fn print_number(&mut self,i:isize)->std::io::Result{
如果释放一些(out)=&mut self.out{
写!(出“号码是{}”,我)?;
}
好(())
}

您还可以简化路径,例如
std::io::Write
std::io::Result
,方法是使用导入,例如
use std::io:{self,Write}
然后将它们更改为
Write
io::Result

即使它看起来是基础性的,
是一些()
通常不是您想要的。通常,您想知道它的
部分
,并想访问内部值,而模式匹配(通过
匹配
如果让
)提供了这两种功能。
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