【问题标题】:How to pass a Arc with a trait as a reference?如何传递具有特征的 Arc 作为参考?
【发布时间】:2018-07-28 19:57:03
【问题描述】:

如何传递对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)

如果我省略了引用,它可以编译,但 Clippy 警告我在这种情况下没有任何意义。

code without reference 上的 Clippy 错误:

  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

【问题讨论】:

    标签: rust rust-clippy


    【解决方案1】:

    您可以改为传递对Arc 内容的引用。

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

    【讨论】:

      【解决方案2】:

      嗯,最简单的解决方法是忽略 Clippy。 Clippy 中的许多 lint 并不专门在基本编译器中,因为它们可能是错误的或不适用的。除此之外,Arc 已经是一种参考,使用&amp;Arc&lt;_&gt;(或&amp;Rc&lt;_&gt;)几乎没有多大意义。

      其次,正如 red75prime 所说,您可以将函数更改为采用&amp;A

      最后,如果你真的想安抚 Clippy,你可以照它说的做:

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

      你必须这样做的原因是你只能强制“最外层”的间接层。 letArc&lt;B&gt; 强制转换为 Arc&lt;A&gt;,然后创建指向它的指针。

      如果出于某种原因 ss 需要它的参数是 Arc(例如克隆它),只需忽略 Clippy 或禁用该 lint。如果没有理由 ss 需要它的参数是 Arc(你只需要它里面的内容),请将 ss 更改为 &amp;A

      最后一个主要是为了完整性。

      【讨论】:

      • 我要添加到倒数第二段——如果ss 总是 需要克隆Arc,它应该只需要Arc&lt;A&gt;按值,让调用者决定是否需要克隆。
      猜你喜欢
      • 1970-01-01
      • 2019-08-29
      • 2011-06-25
      • 1970-01-01
      • 2018-08-19
      • 1970-01-01
      • 2021-07-28
      • 1970-01-01
      • 2011-12-15
      相关资源
      最近更新 更多