rust 修改泛型类型的向量

fcwjkofz  于 2023-03-30  发布在  其他
关注(0)|答案(1)|浏览(69)

我有一个函数,它接受一个特定类型(泛型)的向量作为输入。如果给定类型有一个属性,我想创建一个修改过的版本,并将其写入输出缓冲区。如果类型与用例无关,只需跳过这一步。因此,沿着以下行

use std::io;

pub fn write_obj_to_buf<T>(
    obj_vec: &Vec<T>,
    output: &mut dyn io::Write,
) -> Result<(), Box<dyn Error>> {

    // new_vec = empty vector
    // for each element in obj_vec
    // if T=something specific -> append to new_vec modified version (how to modify?), else append existing
    
    unsafe {
        let buf_view: &[u8] = slice::from_raw_parts(
            new_vec.as_ptr() as *const u8,
            new_vec.len() * mem::size_of::<T>(),
        );
        output.write_all(buf_view)?;
    }
    Ok(())
}

在Rust中,有什么惯用的方法可以做到这一点?我是泛型的新手,不确定std::any::Any是否与此相关?

zwghvu4y

zwghvu4y1#

在这种情况下,惯用的方法是描述你所有的类型集,并为它实现trait。如果你不需要为一些类型做,只是仍然为空实现。参见示例:

trait MyTrait {
    fn foo(&self) -> ();
}

struct Foo;
struct Bar;

impl MyTrait for Foo {
    fn foo(&self) -> () {
        println!("Hello from Foo");
    }
}

impl MyTrait for Bar {
    fn foo(&self) -> () {
        //println!("Hello from Bar");
    }
}

fn f(v: &Vec<Box<dyn MyTrait>>) -> () {
    v.iter().for_each(|item| item.foo());
}

fn main() {
    let v: Vec<Box<dyn MyTrait>> = vec![Box::new(Foo), Box::new(Bar)];
    f(&v);
}

// output: Hello from Foo

另一种方法是创建包含所有类型的enum MyEnum并实现其行为。例如:

enum MyEnum {
    Foo(u32),
    Bar(String),
}

impl MyEnum {
    pub fn foo_here(&self) -> () {
        match self {
            MyEnum::Foo(_) => println!("Hello from Foo"),
            MyEnum::Bar(_) => (),
        }
    }
}

fn f(v: &Vec<MyEnum>) -> () {
    v.iter().for_each(|item| item.foo_here());
}

fn main() {
    let v: Vec<MyEnum> = vec![MyEnum::Foo(2), MyEnum::Bar("".into())];
    f(&v);
}

相关问题