文档中是否提到在函数的参数前面添加关键字mut的可能性?

时间:2018-06-27 09:21:26

标签: rust mutability function-signature

我有一个基本的Reader,其中封装了一些通用元素:

pub struct Reader<R> {
    inner: R,
    order: Endian,
    first_ifd_offset: usize,
}

impl<R: Read + Seek> Reader<R> {
    pub fn new(reader: R) -> Result<Reader<R>> {
        let mut order_raw = [0, 0];
        reader.read_exact(&mut order_raw)?;
        let magic_number = u16::to_be(u16::from_bytes(order_raw));
        /* ... */
   }
}

这不能编译并产生以下错误:

error[E0596]: cannot borrow immutable argument `reader` as mutable
  --> src/reader.rs:17:9
   |
15 |     pub fn new(reader: R) -> Result<Reader<R>> {
   |                ------ consider changing this to `mut reader`
16 |         let mut order_raw = [0, 0];
17 |         reader.read_exact(&mut order_raw)?;
   |         ^^^^^^ cannot borrow mutably

当我通过值获取参数时,new函数应该是reader元素的新所有者。编译器建议我在函数参数前面添加一个mut关键字。

文档中是否提到可以在函数参数前面添加mut关键字的可能性?我找不到提及它的资源。

标准库的BufReader结构具有一个 类似的new函数,并且不使用mut关键字,而是使用unsafe 体内的阻止代码。 unsafe是否阻止在函数签名中使用mut

2 个答案:

答案 0 :(得分:2)

我认为编译器在说出添加mut的位置非常精确。通常,编译器会尝试在特定位置加下划线:

pub fn new(mut reader: R) -> Result<Reader<R>>

现在可以在功能中对阅读器进行突变。行为类似于:

pub fn new(reader: R) -> Result<Reader<R>, Error> {
    let mut reader = reader;
    // ...

据我所知,这只是本书中的mentioned once,但在某种意义上或多或少地是这是一种模式,您也可以在函数中使用它

unsafe does not fix it, it's UB

  

不可变数据-即通过共享引用到达的数据或let绑定所拥有的数据),除非该数据包含在UnsafeCell<U>中。

答案 1 :(得分:2)

这是隐含的,但书中没有直接提及。 some_excelfile_view和函数参数都是模式,因此就像可以在let中使用mut一样,也可以在参数中使用它。