When I'm passing a object by reference to a struct's new()
method, and the struct will own the object, is it more conventional to:
to_owned()
in the new()
new()
, and pass by value, moving itI can think of pros and cons of each in terms of clarity and separation-of-concerns.
#[derive(Clone)]
struct MyState;
struct MyStruct {
state: MyState,
}
impl MyStruct {
pub fn new_by_ref(state: &MyState) -> Self {
MyStruct {
state: state.to_owned(),
}
}
pub fn new_by_val(state: MyState) -> Self {
MyStruct { state }
}
}
fn main() {
let state1 = MyState;
let struct1 = MyStruct::new_by_ref(&state1);
let state2 = MyState;
let struct2 = MyStruct::new_by_val(state2.clone());
}
Pass-by-references is more efficient than pass-by-value, because it does not copy the arguments. The formal parameter is an alias for the argument. When the called function read or write the formal parameter, it is actually read or write the argument itself.
The reason is simple: if you passed by value, a copy of the object had to be made and, except for very small objects, this is always more expensive than passing a reference.
2) For passing large sized arguments: If an argument is large, passing by reference (or pointer) is more efficient because only an address is really passed, not the entire object.
Basically, pass-by-value means that the actual value of the variable is passed and pass-by-reference means the memory location is passed where the value of the variable is stored.
Pass by value.
This way, the program can avoid unnecessarily doubly-allocating the value if the caller no longer needs it.
In many cases, I recommend accepting anything that can be made into the owned type. This is easily demonstrated with String
:
struct MyStruct {
state: String,
}
impl MyStruct {
fn new(state: impl Into<String>) -> Self {
let state = state.into();
MyStruct { state }
}
}
fn main() {
let struct1 = MyStruct::new("foo");
let struct2 = MyStruct::new(String::from("bar"));
}
See also:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With