如何用PyO3在Rust中返回NumPy数组并解决生命周期错误?
修复Rust与PyO3交互中的生命周期错误
错误根源
代码里的核心问题是:循环内创建的String s是局部变量,每次循环迭代结束后,s会被Rust自动销毁。但你把s的引用&s存入了result,这会导致引用指向已经被释放的内存——Rust的所有权机制禁止这种悬空引用,因此抛出「缺失生命周期说明符」的错误,本质是Vec<&str>里的引用没有合法的生命周期来源。
修复方案
把返回类型从PyResult<Vec<&str>>改成PyResult<Vec<String>>,直接返回拥有所有权的字符串集合,而非引用。这样每个字符串的所有权都转移到Vec中,彻底避免悬空引用问题。
修复后的完整代码
use pyo3::{wrap_pyfunction, PyModule, PyResult, Python}; use numpy::PyArrayDyn; #[pymodule] fn dnd_images(py: Python, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(get_shape_instructions, m)?)?; Ok(()) } #[pyfunction] fn get_shape_instructions(py: Python, array: &PyArrayDyn<u16>) -> PyResult<Vec<String>> { let array = unsafe { array.as_array() }; let mut result = Vec::new(); for element in array { let s: String = element.to_string(); result.push(s); } Ok(result) }
关键修改点
- 返回类型调整:将
Vec<&str>改为Vec<String>,让Vec拥有字符串的所有权,消除生命周期依赖 - 变量初始化:原代码仅声明
result未初始化,修复后直接用Vec::new()创建空集合 - 所有权转移:循环内直接
push(s),把String的所有权转移给Vec,而非推送临时变量的引用
PyO3会自动将Vec<String>转换为Python的字符串列表,Python端调用时可以直接使用,完全满足需求。
内容的提问来源于stack exchange,提问作者RubidiumCode
相关产品推荐
相关产品推荐

