为啥 Clippy 建议传递 Arc 作为参考?
Posted
技术标签:
【中文标题】为啥 Clippy 建议传递 Arc 作为参考?【英文标题】:Why does Clippy suggests passing an Arc as a reference?为什么 Clippy 建议传递 Arc 作为参考? 【发布时间】:2019-08-29 18:42:55 【问题描述】:我正在检查我的代码中的 Clippy 发现,发现 the pedantic rule needless_pass_by_value
可能是误报。
上面写着:
警告:此参数是按值传递的,但不会在函数体中使用
帮助:考虑改为参考:
&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
【问题讨论】:
【参考方案1】:调用arc_taker(arc.clone())
会增加引用计数,从arc_taker
返回会再次减少引用计数。在这种情况下这是没有用的,因为main
的arc
变量已经在整个调用期间保持Arc
处于活动状态。对它的引用就足够了。无需增加和减少引用计数。
在您的具体示例中,arc_taker
甚至不关心它是否由Arc
管理。它只关心Mutex
到lock
,所以为了减少你的功能限制,只需使用&Mutex<MyStruct>
。
如果你想对它做任何Arc
特定的事情,比如获取weak_count
或其他东西,那么使用&Arc<..>
是有意义的。如果您的函数将保留 Arc 的克隆,那么只有按值获取 Arc
才有意义,因为调用者可以决定通过调用 .clone()
来给您额外的引用(从而碰撞引用计数),或者给你它自己的Arc
的所有权(因此不会增加引用计数)。
【讨论】:
很好的答案。 FWIW,here's my version of the&Mutex<MyStruct>
solution.(当然,这使 arc_taker
成为一个坏名字,因为它不需要 Arc
。)
这里有一个普遍的基本原则可能一文不值:一个函数应该只做它正常工作所需的尽可能多的假设,这应该反映在它所采用的参数类型中.这与推荐使用&str
与&String
的原则相同。
@MatthieuM。是的,这是一个很好的补充。在这种特定情况下,这也意味着它甚至不应该采用&Mutex
,因为无论如何该函数总是将其锁定。它应该只需要一个&MyStruct
,并将锁定留给调用者。然后,已经为其他事情锁定互斥锁的调用者也可以调用该函数,而无需先解锁互斥锁。 (但我假设这个问题来自的原始代码不仅仅是.lock().something()
。)
@AkinerAlkan 我想我不知道为什么你会认为这是一个 false positive 的clippy lint。 arc_taker
的主体不需要消耗Arc
,因此可以重写以接受&Arc
。这就是 lint 所说的。您可以出于任何原因选择忽略它,但这不会使其 false.
@AkinerAlkan 打破这个原则意味着限制你的函数的使用方式。如果你的代码的其他部分有一个Rc<Mutex>
或只是一个Box<Mutex>
,如果它不能使用你的函数,那就太可惜了,因为它不必要地需要一个Arc<Mutex>
。如果您确实需要Arc
,则在引用就足够时按值取值不仅意味着性能下降(两次写入原子),而且还会使界面不符合人体工程学:arc_taker(a)
会消耗 a,因此用户该函数需要调用.clone()
而不是只写&a
。以上是关于为啥 Clippy 建议传递 Arc 作为参考?的主要内容,如果未能解决你的问题,请参考以下文章
为啥St. Joan of Arc是圣女贞德?Arc是啥意思?