我对 Rust 很陌生,我的第一个“严肃”项目涉及使用 PyO3 为一个小型 Rust 库编写 Python 包装器。这基本上很轻松,但我正在努力研究如何将 Rust 上的惰性迭代器暴露Vec
给 Python 代码。
到目前为止,我一直在收集迭代器产生的值并返回一个列表,这显然不是最好的解决方案。这是一些说明我的问题的代码:
use pyo3::prelude::*;
// The Rust Iterator, from the library I'm wrapping.
pub struct RustIterator<'a> {
position: usize,
view: &'a Vec<isize>
}
impl<'a> Iterator for RustIterator<'a> {
type Item = &'a isize;
fn next(&mut self) -> Option<Self::Item> {
let result = self.view.get(self.position);
if let Some(_) = result { self.position += 1 };
result
}
}
// The Rust struct, from the library I'm wrapping.
struct RustStruct {
v: Vec<isize>
}
impl RustStruct {
fn iter(&self) -> RustIterator {
RustIterator{ position: 0, view: &self.v }
}
}
// The Python wrapper class, which exposes the
// functions of RustStruct in a Python-friendly way.
#[pyclass]
struct PyClass {
rust_struct: RustStruct,
}
#[pymethods]
impl PyClass {
#[new]
fn new(v: Vec<isize>) -> Self {
let rust_struct = RustStruct { v };
Self{ rust_struct }
}
// This is what I'm doing so far, which works
// but doesn't iterate lazily.
fn iter(&self) -> Vec<isize> {
let mut output_v = Vec::new();
for item in self.rust_struct.iter() {
output_v.push(*item);
}
output_v
}
}
我试图RustIterator
用 Python 包装器来包装这个类,但我不能使用 PyO3 的#[pyclass]
proc。带有生命周期参数的宏。我调查pyo3::types::PyIterator
过,但这看起来像是从 Rust 访问 Python 迭代器的一种方式,而不是相反的方式。
如何RustStruct.v
在 Python 中访问惰性迭代器?可以安全地假设Vec
always 派生Copy
and中包含的类型Clone
,并且需要 Python 端的一些代码的答案是可以的(但不太理想)。