首页 > 解决方案 > 如何创建一个返回泛型类型的修改实例的泛型函数?

问题描述

我有许多泛型函数需要返回泛型的新实例。但是,泛型中的字段是未知的,但我需要获取/设置字段值来创建实例(简单的默认值不起作用)。对于原始字段,我可以更新我的结构,但对于 Vector 或 HashMap 类型的字段,我会收到错误消息:

the size for values of type `[usize]` cannot be known at compilation time

这是我的问题的一个最小工作示例:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=6db1dd0b5982eca526725f4e5b423263

trait MyTrait {
    fn id(&self) -> &usize;
    fn id_mut(&mut self) -> &mut usize;

    fn data(&self) -> &[usize];
    fn data_mut(&mut self) -> &mut [usize];
}

#[derive(Debug)]
struct MyStruct {
    id: usize,
    data: Vec<usize>,
}

impl MyTrait for MyStruct {
    fn id(&self) -> &usize {
        &self.id
    }
    fn id_mut(&mut self) -> &mut usize {
        &mut self.id
    }
    fn data(&self) -> &[usize] {
        &self.data
    }
    fn data_mut(&mut self) -> &mut [usize] {
        &mut self.data
    }
}

impl Default for MyStruct {
    fn default() -> MyStruct {
        MyStruct {
            id: 0,
            data: vec![],
        }
    }
}

fn my_func<T: MyTrait + Default>() -> T {
    let mut d = T::default();
    // this correctly updates the struct field "id" to 26
    *d.id_mut() = 26;
    // this however, does not work. i get an error:
    // the size for values of type `[usize]` cannot be known at compilation time
    *d.data_mut() = vec![1, 2, 3].as_slice();
    d
}

fn main() {
    let _my_instance = my_func::<MyStruct>();
}

如何创建一个返回泛型类型实例的泛型函数?

标签: rust

解决方案


对于您的,Default实例是一个空的,但您将它公开为一个可变切片。这是毫无意义的,因为您无法更改可变切片的长度;你只能改变现有的元素。MyStructdataVec

您将需要改为公开,data以便&mut Vec<usize>您可以插入元素。不可变的 getter 可以保持不变。

trait MyTrait {
    fn id(&self) -> &usize;
    fn id_mut(&mut self) -> &mut usize;

    fn data(&self) -> &[usize];
    fn data_mut(&mut self) -> &mut Vec<usize>;
}

并更改更新它的代码:

fn my_func<T: MyTrait + Default>() -> T {
    let mut d = T::default();
    *d.id_mut() = 26;
    *d.data_mut() = vec![1, 2, 3];
    d
}

推荐阅读