我看到了这个问题,解释了serde_json
是如何通过引用或取得控制权来读取和写入Readers/Writers
的。看起来很好理解。
但对于Write
,我不明白它是如何工作的 - 所有Write
方法都需要一个&mut self
, 因此我认为如果我传递一个只知道其参数是引用到某些东西的方法,它无法使用它。但是,即使我向一个只接受非可变引用的方法传递了一个方法,它也可以编译并正常工作,尽管我正在将一个非可变引用传递给一种以某种方式写入所引用文件的方法:
extern crate serde_json;
use std::fs::OpenOptions;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
let file = OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open("/tmp/serde.json")?;
// why does this work?
serde_json::to_writer(&file, &10)?;
Ok(())
}
我正在传递一个 &File
- 如预期的那样,如果我直接在一个 File
上调用任何 Write
的方法,它是不起作用的:
use std::io::{self, Write};
use std::fs::OpenOptions;
fn main() -> io::Result<()> {
let file = OpenOptions::new()
.create(true)
.write(true)
.truncate(true)
.open("/tmp/wtf")?;
let file_ref = &file;
// this complains about not having a mutable ref as expected
file_ref.write(&[1,2,3])?;
Ok(())
}
error[E0596]: cannot borrow `file_ref` as mutable, as it is not declared as mutable
--> test.rs:12:5
|
10 | let file_ref = &file;
| -------- help: consider changing this to be mutable: `mut file_ref`
11 | // this complains about not having a mutable ref as expected
12 | file_ref.write(&[1,2,3])?;
| ^^^^^^^^ cannot borrow as mutable
那么问题出在哪里呢?是
serde_json
破坏了类型系统,还是这是类型系统的一个有意的特性?如果是后者,它如何工作,为什么会这样工作呢?
Read
或Write
的通用函数时,应该始终按值传递,而不是按引用传递,就像serde
一样。 - rodrigo