Hi there,
I'm trying to make sure I fully understand how ownership works in Rust and I've run into something that's stumped me.
I wanted to implement a reset
function where you could pass a &mut
object and assign a new default value to it - essentially an out param. (I know returning a value is the more idiomatic approach but this is just a toy example).
Now in order for this to work, I learned that you must use mem::replace
to ensure there is always a valid owner (I found this answer to this SO question quite helpful - memory - mem::replace in Rust - Stack Overflow). This now makes sense to me and is the code present in reset_replace
below.
What I don't understand is how the code in reset_deref
is working.
From what I can tell the line *my_type = new_type
is performing a Copy
, but based on what I've read, struct
s are not copyable by default and must use either the #[derive(Copy)]
(and/or) #[derive(Clone)]
trait. I am coming from C++ and maybe that part of my brain is confusing me .
Is *my_type
giving me the binding as opposed to the value? (is that the correct terminology?). And which is the preferred approach, the code used in _replace
or _deref
?
I'd be incredibly grateful if someone could please put me out of my misery
(I pasted the code into Godbolt to see what the generated assembly looks like and it appears to be quite similar - Compiler Explorer)
use std::mem;
pub struct MyOtherType {
a_float: f64,
}
pub struct MyType {
an_int: u64,
a_string: String,
another_type: MyOtherType,
}
pub fn reset_replace(my_type: &mut MyType) {
let new_type = MyType {
an_int: 7,
a_string: String::new(),
another_type: MyOtherType { a_float: 2.0 },
};
mem::replace(my_type, new_type);
}
pub fn reset_deref(my_type: &mut MyType) {
let new_type = MyType {
an_int: 4,
a_string: String::new(),
another_type: MyOtherType { a_float: 1.0 },
};
*my_type = new_type;
}
Thank you very much for your help!