代码之家  ›  专栏  ›  技术社区  ›  Shahzeb Khan

锈函数返回泛型特征

  •  0
  • Shahzeb Khan  · 技术社区  · 6 年前

    特质

    pub trait DbfFile{
        fn new(fields: HashMap<String, FieldValue>) -> Self;
    }
    

    这些结构是

    pub struct InsertableAttachable {
        pub f1: String,
        pub f2: String,
        pub f3: String,
        pub f4: i8,
    }
    
    impl DbfFile for InsertableAttachable{
        fn new(fields: HashMap<String, FieldValue, RandomState>) -> Self {
            InsertableAttachable {
                // fields
            }
        }
    }
    
    
    
    // Converting this to generic
    
    impl InsertableAttachable{
        pub fn get_data_vector(mut iter: DatabaseRecordIterator) -> Vec<InsertableAttachable>{
            let mut db_data: Vec<InsertableAttachable> = vec!();
            while let Some(table_row) = iter.next() {
                let fields = table_row.fields;
                db_data.push(InsertableAttachable::new(fields));
            };
            db_data
        }
    }
    

    还有另一个结构

    pub struct InsertableAttached {
        pub f1: String,
        pub f2: i32,
        pub f3: i32,
    }
    
    impl DbfFile for InsertableAttached {
        fn new(fields: HashMap<String, FieldValue, RandomState>) -> Self {
            InsertableAttached {
               // fields
            }
        }
    
    }
    
    // Converting this to generic
    
    impl InsertableAttached{
        pub fn get_data_vector(mut iter: DatabaseRecordIterator) -> Vec<InsertableAttached>{
            let mut db_data: Vec<InsertableAttached> = vec!();
            while let Some(table_row) = iter.next() {
                let fields = table_row.fields;
                db_data.push(InsertableAttached::new(fields));
            };
            db_data
        }
    }
    

    this returns box / struct this one

    以下函数有编译时错误

    error[E0277]: the size for values of type `(dyn models::traits::DbfFile + 'static)` cannot be known at compilation time
      --> src/dbf.rs:75:1
       |
    75 | / pub fn get_data_vector(&mut iter: DatabaseRecordIterator) -> Vec<DbfFile>{
    76 | |     let mut db_data: Vec<DbfFile> = vec!();
    77 | |     while let Some(table_row) = iter.next() {
    78 | |         let fields = table_row.fields;
    ...  |
    81 | |     db_data
    82 | | }
       | |_^ doesn't have a size known at compile-time
       |
       = help: the trait `std::marker::Sized` is not implemented for `(dyn models::traits::DbfFile + 'static)`
       = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
       = note: required by `std::vec::Vec`
    
    error[E0038]: the trait `models::traits::DbfFile` cannot be made into an object
      --> src/dbf.rs:75:1
       |
    75 | pub fn get_data_vector(&mut iter: DatabaseRecordIterator) -> Vec<DbfFile>{
       | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `models::traits::DbfFile` cannot be made into an object
    
    0 回复  |  直到 6 年前
        1
  •  0
  •   Matthias247    6 年前

    为了能够通过动态分派返回异类集合,您需要将结果框选出来:

    pub fn get_data_vector(&mut iter: DatabaseRecordIterator) -> Vec<Box<dynDbfFile>>
    

    但是,您将得到以下错误:

    | pub fn get_data_vector(&mut iter: DatabaseRecordIterator) -> Vec<Box<dyn DbfFile>> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `DbfFile` cannot be made into an object
    |
    

    Self -这对于每个实现都是不同的。您需要将其更改为公共类型,以使trait对象安全(允许动态分派)。

    另一种方法是通过枚举返回多个类型:

    enum GetDataVectorResult {
        Attachable(InsertableAttachable),
        Attached(InsertableAttached),
    }
    
    pub fn get_data_vector(&mut iter: DatabaseRecordIterator) -> Vec<GetDataVectorResult>
    
    推荐文章