为什么 Clippy 建议传递 Arc 作为参考?

Why does Clippy suggests passing an Arc as a reference?

我正在检查代码中的 Clippy 结果,发现 the pedantic rule needless_pass_by_value 可能是误报。

上面写着:

warning: this argument is passed by value, but not consumed in the function body

help: consider taking a reference instead: &Arc<Mutex<MyStruct>>

因为克隆 Arc 只是引用计数,所以移动 Arc 应该是个不错的主意。发送参考而不是 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

调用 arc_taker(arc.clone()) 增加引用计数,从 arc_taker 返回再次减少它。在这种情况下这是无用的,因为 mainarc 变量在整个调用期间已经使 Arc 保持活动状态。对它的引用就足够了。无需上下颠簸引用计数。

在您的具体示例中,arc_taker 甚至不关心它是否由 Arc 管理。它只关心 Mutexlock,所以为了使您的函数限制更少,只需取 &Mutex<MyStruct> 即可。

如果您想对它做任何 Arc 特定的事情,比如获得 weak_count 或其他东西,那么获得 &Arc<..> 是有意义的。如果您的函数要保留 Arc 的克隆,那么只有按值获取 Arc 才有意义,因为这样调用者就可以决定通过调用 .clone() 来为您提供对它的额外引用(从而增加引用计数),或者让您拥有它自己的 Arc(因此不会增加引用计数)。