【问题标题】:Cloning an Rc pointer over a trait object in Rust?在 Rust 的 trait 对象上克隆 Rc 指针?
【发布时间】:2021-09-22 11:25:09
【问题描述】:

我正在学习 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);
}

【问题讨论】:

标签: rust traits smart-pointers trait-objects


【解决方案1】:

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

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&lt;SomeThing&gt; 而不是您正在寻找的 Rc&lt;dyn SomeTrait&gt;,这可以通过向 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&lt;SomeThing&gt;Rc&lt;dyn SomeTrait&gt;完全不兼容的值,因此无法将一个用于另一个。

解决方案是简单地正确输入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,而第二个(也是最后一个调用)仍然需要它。

【讨论】:

  • 值得注意:您可以Rc&lt;SomeThing&gt; 转换为Rc&lt;dyn SomeTrait&gt;,但它需要显式转换。 some_function(Rc::clone(&amp;s) as Rc&lt;dyn SomeTrait&gt;); 将编译并工作。这是由于当前不稳定的CoerceUnsized trait。
猜你喜欢
  • 1970-01-01
  • 2016-04-08
  • 1970-01-01
  • 2017-05-27
  • 2016-06-05
  • 1970-01-01
  • 2011-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多