我有一个表示数据网格的结构,以及行和列的访问器。我试图为返回迭代器而不是Vec的行和列添加访问器。
use std::slice::Iter;
#[derive(Debug)]
pub struct Grid<Item : Copy> {
raw : Vec<Vec<Item>>
}
impl <Item : Copy> Grid <Item>
{
pub fn new( data: Vec<Vec<Item>> ) -> Grid<Item> {
Grid{ raw : data }
}
pub fn width( &self ) -> usize {
self.rows()[0].len()
}
pub fn height( &self ) -> usize {
self.rows().len()
}
pub fn rows( &self ) -> Vec<Vec<Item>> {
self.raw.to_owned()
}
pub fn cols( &self ) -> Vec<Vec<Item>> {
let mut cols = Vec::new();
for i in 0..self.height() {
let col = self.rows().iter()
.map( |row| row[i] )
.collect::<Vec<Item>>();
cols.push(col);
}
cols
}
pub fn rows_iter( &self ) -> Iter<Vec<Item>> {
// LIFETIME ERROR HERE
self.rows().iter()
}
pub fn cols_iter( &self ) -> Iter<Vec<Item>> {
// LIFETIME ERROR HERE
self.cols().iter()
}
}
rows_iter
和cols_iter
这两个函数都有同样的问题:error: borrowed value does not live long enough
。我已经尝试了很多东西,但是把它简化回到最简单的事情上来发布。
答案 0 :(得分:2)
您可以使用返回into_iter
的方法std::vec::IntoIter
。函数iter
通常只借用迭代的数据源。 into_iter
拥有数据源的所有权。因此,矢量将与实际数据一样长。
pub fn cols_iter( &self ) -> std::vec::IntoIter<Vec<Item>> {
self.cols().intoiter()
}
但是,我认为你的网格类型的设计可以大大改进。总是克隆一个向量并不是一件好事(仅举一个问题)。
答案 1 :(得分:1)
迭代器只包含对原始数据结构的借用引用;他们不接受它的所有权。因此,向量必须比该向量上的迭代器长寿。
rows
和cols
分配并返回新的Vec
。 rows_iter
和cols_iter
正在尝试在临时Vec
上返回迭代器。在Vec
或rows_iter
返回之前,此cols_iter
将被取消分配。这意味着必须在函数返回之前释放Vec
上的迭代器。但是,您试图从函数返回迭代器,这将使迭代器的活动时间长于函数的结尾。
根本无法使rows_iter
和cols_iter
按原样编译。我认为这些方法根本就没有必要,因为您已经提供了公开rows
和cols
方法。