如何对生命周期相关的两个对象进行装箱?

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

我正在尝试使用

parquet
库在函数中创建一个记录迭代器对象,可以使用我自己的称为
RecordIterator
的特征进行迭代。看起来像这样:

    fn blah(dataset_info: DatasetInfo, file: File) -> Result<Box<dyn RecordIterator<Item=Record>>, Box<dyn Error>> {
        let reader = SerializedFileReader::new(file).unwrap();
        let iter = (&reader).get_row_iter(None).unwrap();
        let column_type = *dataset_info.column_type.clone();
        let iterator = ParquetRecordIterator {
            iterator: iter,
            column_type: column_type,
            i: 0,
        };
        Ok(Box::new(iterator))
    }

问题是,因为 iter 的生命周期附加到它所创建的 SerializedFileReader 变量,所以返回 ParquetRecordIterator (实现 RecordIterator 特征)对象会抱怨一个错误:

cannot return value referencing local variable `reader` [E0515]

我理想情况下不想破坏这里的抽象,那么您建议如何实现这个功能?实际上,我想打破读取器和迭代器之间的生命周期链接,但不确定如何最好地做到这一点,或者使用不同的 parquet API 来做到这一点。

我尝试将文件读取器包装在

Box::new
中,希望生命周期不会与堆中的对象绑定,但不幸的是,这似乎不起作用。

我没有尝试过任何库来处理自引用结构,因为似乎不推荐它们,所以我希望有一种标准方法来解决这个问题。

我没有尝试过查看其他镶木地板库。

rust parquet
1个回答
0
投票

这是 Rust 中的一个难题,因为你本质上是在尝试创建一个 self-referential 结构。

幸运的是,您通常不需要解决这个问题,因为您使用的库提供了对此用例的直接支持:

impl IntoIterator for SerializedFileReader<File>
。所以:

    fn blah(dataset_info: DatasetInfo, file: File) -> Result<Box<dyn RecordIterator<Item=Record>>, Box<dyn Error>> {
        let reader = SerializedFileReader::new(file).unwrap();
        let iter = reader.into_iter();
        let column_type = *dataset_info.column_type.clone();
        let iterator = ParquetRecordIterator {
            iterator: iter,
            column_type: column_type,
            i: 0,
        };
        Ok(Box::new(iterator))
    }
© www.soinside.com 2019 - 2024. All rights reserved.