问题
I am checking Clippy findings in my code and found that the pedantic rule needless_pass_by_value might be a false positive.
It says that:
warning: this argument is passed by value, but not consumed in the function body
help: consider taking a reference instead:
&Arc<Mutex<MyStruct>>
Since cloning the Arc
is only reference counting, moving the Arc
should not be bad idea. Does it really make any difference in terms of quality and performance to send a reference instead of a value for the Arc
?
#![warn(clippy::pedantic)]
use std::sync::{Arc, Mutex};
fn main() {
let my_struct = MyStruct { value: 3 };
let arc = Arc::new(Mutex::new(my_struct));
arc_taker(arc.clone());
}
fn arc_taker(prm: Arc<Mutex<MyStruct>>) {
prm.lock().unwrap().do_something();
}
struct MyStruct {
value: i32,
}
impl MyStruct {
fn do_something(&self) {
println!("self.value: {}", self.value);
}
}
Playground
回答1:
Calling arc_taker(arc.clone())
increments the reference count, and returning from arc_taker
decrements it again. This is useless in this case, since the arc
variable of main
already keeps the Arc
alive during the entire call. A reference to it would already suffice. No need to bump the reference count up and down.
In your specific example, arc_taker
doesn't even care that it is managed by an Arc
. All it cares about is that there is a Mutex
to lock
, so to make your function less restrictive, just take a &Mutex<MyStruct>
instead.
If you wanted to do any Arc
-specific things to it, like getting the weak_count
or something, taking a &Arc<..>
would make sense. If your function would keep a clone of the Arc around, only then it would make sense to take an Arc
by value, because then the caller can decide to give you an additional reference to it by calling .clone()
(thus bumping the reference count), or to give you ownership of its own Arc
(and thus not bumping the reference count).
来源:https://stackoverflow.com/questions/55576425/why-does-clippy-suggests-passing-an-arc-as-a-reference