【问题标题】:How to create trait object from boxed trait?如何从盒装特征创建特征对象?
【发布时间】:2019-01-07 18:41:03
【问题描述】:

我想使用 DST 并遇到以下情况

我有以下 trait 可以获取 Box 并在外部返回新的 Trait 对象:

pub trait MyTrait {
    fn create_from_box(boxed: Box<Self>) -> Self
    where
        Self: Sized;
}

我关注不同的结构,这些结构正在实现MyTrait 结构第一结构;

impl MyTrait for FirstStruct {
    fn create_from_box(boxed: Box<FirstStruct>) -> FirstStruct {
        FirstStruct // Build another struct with some logic and boxed struct values
    }
}

struct SecondStruct;

impl MyTrait for SecondStruct {
    fn create_from_box(boxed: Box<SecondStruct>) -> SecondStruct {
        SecondStruct // Build another struct with some logic and boxed struct values
    }
}

我有一个函数可以在某些条件逻辑中获取我的特征对象

fn get_my_trait_object() -> Box<MyTrait> {
    let condition = true; // Retrieved via some logic .

    match condition {
        true => Box::new(FirstStruct),
        false => Box::new(SecondStruct),
    }
}    

然后我有以下函数,它将我的 trait 对象作为装箱值,然后将其传递给 MyTrait 静态方法。

然后它会尝试创建一个新的 MyTrait 对象,该对象将在以后使用。

pub fn main() {
    let boxed = get_my_trait_object();
    let desired_trait_object = MyTrait::create_from_box(boxed);
}

这里的主要问题是,当我执行代码时,我得到以下两个不同的错误:

  • 在编译时无法知道 dyn MyTrait 类型值的大小
  • 所有局部变量都必须具有静态已知大小

我怎样才能解决这些错误并实现我想要做的事情?

Playground

【问题讨论】:

  • 我不明白你在做什么。 create_from_box 不会尝试返回 trait 对象,而是返回具体类型(这是不可能的,因为在编译时不知道 boxed 的具体类型)。
  • 我正在尝试生成一个关于动态盒装类型的新具体类型。我不知道这是可能的,但如果这不可能,我该如何实现这个需求?
  • @Boiethios,我真的需要使用as_any() 和downcast_ref() 吗?由于这种解决方法是先向上转换特征然后手动向下转换,我认为可能有更好的解决方案。
  • 你想让desired_trait_object拥有什么类型?

标签: rust


【解决方案1】:

即使您的类型被装箱,您也可以使用self(请参阅into_vec),因此您的解决方案可能是。

pub trait CreateFromBox {
    fn create_from_box(self: Box<Self>) -> Self;
}

#[derive(Debug, Clone)]
struct Foo(u32);
impl CreateFromBox for Foo {
    fn create_from_box(self: Box<Self>) -> Self {
        Self(self.0 + 1)
    }
}

fn main() {
    let a: Box<Foo> = Box::new(Foo(3));
    let tmp = a.clone();
    let b: Foo = tmp.create_from_box();

    println!("{:?} {:?}", a, b);
}

【讨论】:

  • 这样的?我认为您的主要问题是您的get_my_trait_object,它不能按照您认为的方式工作。看起来你想实现工厂模式,它不适用于 rust。
  • 如果我理解的话,这不是 OP 想要的。他想从 trait 对象中沮丧。
  • @Boiethios,这更像是我想要的,试图在我身边相应地实施它。如果可以,请告诉您。
  • @hellow,这与我的意图很接近,但这里的问题是我们正在完全处理像 Box&lt;Foo&gt; 这样的具体对象,我需要从像 Box&lt;CreateFromBox&gt; 这样的特征类型进行推断,这似乎不适用我猜在 Rust 中。
猜你喜欢
  • 2018-08-19
  • 2019-02-16
  • 2015-08-01
  • 1970-01-01
  • 2022-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多