如何从装箱特征对象中获取对结构的引用?

mds*_*mmo 2 generics traits rust

我想将类型的值插入Box<T>到 a 中Vec<Box<Trait>>,然后获取对该值的引用。(T是实现的泛型类型Trait)。返回值的类型应该是&T

下面的实现几乎可以工作,除了无法转换Box<Trait>Box<Any>.

HashSet有 (实验性) get_or_insert(),这对于这个来说是完美的,但似乎没有Vec?的版本

use std::any::Any;

trait A {}
struct B;
impl A for B {}

// How to write this function?
pub fn insert<'a, T>(vector: &mut Vec<Box<dyn A>>, value: T) -> &'a T where T: A {
    // move the value into the vector
    vector.push(Box::new(value));

    // get the reference to the inserted value back
    let it: &Box<dyn Any> = vector.last().unwrap(); // compile error
    match it.downcast_ref::<T>() {
        Some(i) => i,
        None => panic!(),
    }
}

fn main() {
    let mut vec: Vec<Box<dyn A>> = Vec::new();
    let b = B;
    let b_ref = insert(&mut vec, b);
    // can't use b here since moved, so need b_ref
}
Run Code Online (Sandbox Code Playgroud)

Ali*_*yhl 10

您可以定义为所有类型实现的辅助特征,如下所示:

pub trait AToAny: 'static {
    fn as_any(&self) -> &dyn Any;
}

impl<T: 'static> AToAny for T {
    fn as_any(&self) -> &dyn Any {
        self
    }
}
Run Code Online (Sandbox Code Playgroud)

然后要求它为 A 的子类型实现。

pub trait A: AToAny {
}
Run Code Online (Sandbox Code Playgroud)

您现在可以调用.as_any()&dyn A向量中获得的。

pub fn insert<'a, T: A>(vector: &'a mut Vec<Box<dyn A>>, value: T) -> &'a T {
    vector.push(Box::new(value));

    let it: &dyn Any = vector.last().unwrap().as_any();
    match it.downcast_ref::<T>() {
        Some(i) => i,
        None => panic!(),
    }
}
Run Code Online (Sandbox Code Playgroud)