在 Rust 中转换非原始类型

问题描述 投票:0回答:1

我对 Rust 很陌生,所以如果这是一个简单的问题,我深表歉意!

我有以下简化场景,其中我有一个特征和两个实现该特征的结构类型(TypeA 和 TypeB)。然后我有一个特征向量,其中包含 TypeA 和 TypeB 的实例。

稍后,我想根据类型迭代仅属于 TypeA 或 TypeB 的向量和访问字段。下面是我写的。我的尝试是匹配每个项目的类型,然后将装箱特征迭代器向下转换为结构。这适用于

&
引用,但如何实现可变引用
&mut

对于

&
参考,请考虑以下...

use std::any::Any;

trait MyTrait {
    fn do_something(&self);
    fn as_any(&self) -> &dyn Any;
}

struct TypeA{field_a: u16}
impl MyTrait for TypeA {
    fn do_something(&self) {
        println!("TypeA is doing something.");
    }
    fn as_any(&self) -> &dyn Any {
        self
   }
}

struct TypeB{field_b: u16}
impl MyTrait for TypeB {
    fn do_something(&self) {
        println!("TypeB is doing something.");
    }
    fn as_any(&self) -> &dyn Any {
        self
   }
}

fn main() {
    let vec: Vec<Box<dyn MyTrait>> = vec![
        Box::new(TypeA{field_a:10}),
        Box::new(TypeB{field_b:20}),
    ];

    for item in &vec {
        // Downcast the trait object to its concrete type

        if let Some(type_a) = item.as_any().downcast_ref::<TypeA>() {
            type_a.do_something();
            print!("{}", type_a.field_a);
        } else if let Some(type_b) = item.as_any().downcast_ref::<TypeB>() {
            type_b.do_something();
            print!("{}", type_b.field_b);
        } else {
            println!("Unknown type");
        }
    }
}

但是,我想修改向下转型实例中的字段,例如

type_a.field_a = 100;
rust casting immutability traits
1个回答
0
投票

如果您添加一种方法来获得

&mut dyn Any
的特质,您就可以做到这一点:

fn as_any_mut(&mut self) -> &mut dyn Any;

实现方式与

as_any
相同:

fn as_any_mut(&mut self) -> &mut dyn Any {
    self
}

您还需要使

vec
可变,并迭代
&mut vec
而不是
&vec
,然后您就可以执行此操作,例如:

item.as_any_mut().downcast_mut::<TypeA>()

这会给你一个

&mut TypeA


但是,我强烈建议您消费者使用枚举而不是盒装特征对象。如果您需要支持一组封闭的变体,这将更加符合人体工程学。

© www.soinside.com 2019 - 2024. All rights reserved.