在 Rust 的特征对象上克隆一个 Rc 指针?

Cloning an Rc pointer over a trait object in Rust?

我正在学习 Rust,但不明白为什么以下内容不起作用。我想我们无法在 trait 对象上克隆一个 Rc 指针?我如何将这样的引用传递给仅由特征定义的函数,如 some_function?

中所尝试的那样
use std::rc::Rc;

trait SomeTrait {}
struct SomeThing {}
impl SomeTrait for SomeThing {}

fn some_function(s: Rc<dyn SomeTrait>) {}
fn another_function(s: &Rc<dyn SomeTrait>) {}

fn main() {
    let s = Rc::new(SomeThing{});

    // This doesnt work
    some_function(Rc::clone(&s));

    // I could do this
    some_function(s);

    // But then I could not do this
    some_function(s);
    
    // For that matter, neither can I do this
    another_function(&s);
}

如果您查看编译器的错误消息,您会看到:

error[E0308]: mismatched types
   |
14 |     some_function(Rc::clone(&s));
   |                             ^^ expected trait object `dyn SomeTrait`, found struct `SomeThing`
   |
   = note: expected reference `&Rc<dyn SomeTrait>`
              found reference `&Rc<SomeThing>`

这意味着编译器错误地将 s 的类型推断为 Rc<SomeThing> 而不是您正在寻找的 Rc<dyn SomeTrait> ,这可以通过提供一个常用技巧来确认公然输入 let s:

不正确
error[E0308]: mismatched types
  --> src/main.rs:11:17
   |
11 |     let s: () = Rc::new(SomeThing{});
   |            --   ^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `Rc`
   |            |
   |            expected due to this
   |
   = note: expected unit type `()`
                 found struct `Rc<SomeThing>`

由于 Rust 包装器是 invariantRc<SomeThing>Rc<dyn SomeTrait> 完全不兼容的值,没有办法只使用一个为另一个。

解决方案是简单地正确地明确键入 s

use std::rc::Rc;

trait SomeTrait {}
struct SomeThing {}
impl SomeTrait for SomeThing {}

fn some_function(s: Rc<dyn SomeTrait>) {}
fn another_function(s: &Rc<dyn SomeTrait>) {}

fn main() {
    let s: Rc<dyn SomeTrait> = Rc::new(SomeThing{});

    // This doesnt work
    some_function(Rc::clone(&s));
    
    // For that matter, neither can I do this
    another_function(&s);
}

显然中间的两个调用不起作用,因为第一个将 移动 本地 Rc,第二个(和最后一个调用)还想要。