简体   繁体   English

如何通过带有特征的弧作为参考?

[英]How to pass a Arc with a trait as a reference?

How can I pass a reference to Arc<A> so that the following code compiles successfully? 如何传递对Arc<A>的引用,以便以下代码成功编译?

use std::sync::Arc;

trait A {
    fn send(&self);
}

struct B;
impl A for B {
    fn send(&self) {
        println!("SENT");
    }
}

fn ss(a: &Arc<A>) {
    let aa = a.clone();
    aa.send();
}

fn main() {
    let a = Arc::new(B);
    ss(&a);
}

( playground ) 游乐场

If I omit the reference, it compiles okay, but Clippy warns me that in such situation in makes no sense. 如果我省略该引用,它可以编译,但是Clippy警告我在这种情况下是没有意义的。

Clippy error on the code without reference : 代码上的裁剪错误, 无需参考

  Compiling playground v0.0.1 (file:///playground)
warning: this argument is passed by value, but not consumed in the function body
  --> src/main.rs:13:10
   |
13 | fn ss(a: Arc<A>) {
   |          ^^^^^^ help: consider taking a reference instead: `&Arc<A>`
   |
   = note: #[warn(needless_pass_by_value)] on by default
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.186/index.html#needless_pass_by_value

Well, the simplest fix is to just ignore Clippy . 好吧,最简单的解决方法就是忽略Clippy Many of the lints in Clippy aren't in the base compiler specifically because they can be wrong or inapplicable. Clippy中的许多棉绒都不在基本编译器中,因为它们可能是错误的或不适用的。 Besides which, an Arc is already a kind of reference, and taking an &Arc<_> (or &Rc<_> ) rarely makes much sense. 除此之外, Arc已经是一种引用,采用&Arc<_> (或&Rc<_> )很少有意义。

Secondly, as red75prime noted, you can change the function to take &A instead. 其次,正如red75prime指出的那样,您可以将函数更改为&A

Finally, if you really want to appease Clippy, you could just do what it says: 最后,如果您真的想安抚Clippy,则可以按照它说的做:

fn main() {
    let a = Arc::new(B);
    { let a: Arc<A> = a.clone(); ss(&a); }
}

The reason you have to do it this way is that you can only coerce the "outermost" layer of indirection. 您必须采用这种方式的原因是,您只能强迫间接的“最外层”。 The let coerces the Arc<B> into an Arc<A> , then creates a pointer to it. let胁迫的Arc<B>Arc<A> ,然后创建一个指向它的指针。

If there's some reason ss needs its argument to be an Arc (such as cloning it), just ignore Clippy or disable that lint. 如果出于某些原因, ss 需要将其参数设置为Arc (例如克隆),只需忽略Clippy或禁用该功能即可。 If there's no reason ss needs its argument to be an Arc (you just need what's inside it), change ss to take &A instead. 如果没有理由ss 需要其参数为Arc (您只需要其中的内容),则将ss更改为&A

That last one is mostly just for completeness. 最后一个主要是为了完整性。

You can pass a reference to an Arc 's content instead. 您可以改为传递对Arc内容的引用。

fn ss(a: &A) {
    a.send();
}

fn main() {
    let a = Arc::new(B);
    ss(&*a);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM