【问题标题】:Rust: Trait as a return typeRust:特征作为返回类型
【发布时间】:2020-12-31 09:42:48
【问题描述】:

假设有这样的代码:

trait A {
  fn something(&self) -> String
}

struct B {
  things: Vec<u64>
}

struct C {
  thing: Box<&dyn A>
}

impl A for B { ... }

fn create_thing() -> B {
  // 
}

impl C {
  pub fn new() {
    let thing = create_thing();
    C { thing }
  }
}

我的问题是 create_thing 的返回类型究竟应该是什么才能与 Box 匹配,或者返回值应该如何包装以匹配 盒子?

等效的 C# 代码如下所示:

interface A {}
class B : A {}
class C {
  public A field;
  public C() {
    this.field = new B();
  }
}

【问题讨论】:

  • 你为什么要Box&lt;&amp;dyn A&gt;而不是Box&lt;dyn A&gt;
  • 这是一个错误

标签: types rust traits


【解决方案1】:

在您的代码下方查找并稍作调整以使其编译。

我怀疑Box&lt;&amp;dyn A&gt; 不是故意的,因为这意味着 引用本身是堆分配的(不是引用的对象)。 另一方面,Box&lt;dyn A&gt; 匹配您的 C# 示例。

返回类型 create_thing() 对我来说看起来不错,因为它 不假设任何特定类型的存储(堆栈、堆、内部 一个向量...) 的返回值。 你只需要Box这个结果值就可以提供 初始化C时使用它。

但是,如果您想隐藏确切返回的事实 类型是B in create_thing(),你可以这样改 fn create_thing() -&gt; impl A.

如果你真的想返回一个 dyn trait 对象,那么改变 它到fn create_thing() -&gt; Box&lt;dyn A&gt; 并创建盒子 这里而不是C::new()

trait A {
    fn something(&self) -> String;
}

struct B {
    things: Vec<u64>,
}

struct C {
    thing: Box<dyn A>,
}

impl A for B {
    fn something(&self) -> String {
        format!("something on B with {:?}", self.things)
    }
}

fn create_thing() -> B {
    B {
        things: vec![1, 2, 3],
    }
}

impl C {
    pub fn new() -> Self {
        let thing = Box::new(create_thing());
        Self { thing }
    }
}

fn main() {
    let c = C::new();
    println!("{}", c.thing.something());
}

【讨论】:

    猜你喜欢
    • 2022-07-31
    • 2023-01-12
    • 1970-01-01
    • 2021-04-15
    • 2021-06-07
    • 2020-08-17
    • 2021-02-01
    • 2020-07-07
    • 1970-01-01
    相关资源
    最近更新 更多