Reputation: 4455
I have a basic Reader
encapsulating some generic elements:
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));
/* ... */
}
}
This does not compile and produces the following error:
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
As I am getting the argument by value, the new
function should be the new owner of the reader
element. The compiler advises me to to add a mut
keyword in front of the function argument.
Does the documentation mention the possibility of adding the mut
keyword in front of functions' arguments? I was not able to find resources mentioning it.
The BufReader
struct of the standard library has a
similar new
function and does not use a mut
keyword but an unsafe
block code in the body. Does unsafe
prevent the usage of mut
inside the function's signature?
Upvotes: 0
Views: 113
Reputation: 15559
It’s implied but not directly mentioned in the book. Both let
and function arguments are patterns, so just like you can use mut
in let
, you can use it in arguments.
Upvotes: 3
Reputation: 8476
I think the compiler is very precise in saying where to add the mut
. Generally the compiler tries to underline the specific places:
pub fn new(mut reader: R) -> Result<Reader<R>>
It's now possible to mutate the reader in the function. This behaves like:
pub fn new(reader: R) -> Result<Reader<R>, Error> {
let mut reader = reader;
// ...
As far as I know, it's only mentioned once in the book but more or less in sense of It's a pattern, you may use it in functions too.
unsafe
does not fix it, it's UB:
Mutating non-mutable data — that is, data reached through a shared reference or data owned by a
let
binding), unless that data is contained within anUnsafeCell<U>
.
Upvotes: 2