[英]Rust function to return generic trait
我有两个实现相同特征的结构。 我需要一个函数来返回任何这些结构的 object。
特征
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
}
}
以下function有编译时错误
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
您需要对结果进行装箱,以便能够通过动态调度返回异构集合:
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
|
这样做的原因是您的 function 返回Self
- 每个实现都不同。 您需要将其更改为通用类型以使特征对象安全(允许动态分派)。
另一种方法是通过枚举返回多种类型:
enum GetDataVectorResult {
Attachable(InsertableAttachable),
Attached(InsertableAttached),
}
pub fn get_data_vector(&mut iter: DatabaseRecordIterator) -> Vec<GetDataVectorResult>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.