1

我有一个表示数据网格的结构,以及行和列的访问器。我正在尝试为返回迭代器而不是 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. 我已经尝试了很多东西,但把它缩减为最简单的东西在这里发布。

4

2 回答 2

2

您可以使用into_iter返回的方法std::vec::IntoIter。该函数iter通常只借用迭代过的数据源。into_iter拥有数据源的所有权。因此,向量将与实际数据一样长。

pub fn cols_iter( &self ) -> std::vec::IntoIter<Vec<Item>> {
    self.cols().intoiter()
}

但是,我认为您的 Grid 类型的设计可以改进很多。总是克隆一个载体不是一件好事(仅举一个问题)。

于 2015-11-30T07:10:37.390 回答
1

迭代器只包含对原始数据结构的借用引用;他们不拥有它。因此,向量必须比该向量上的迭代器寿命更长。

rowscols分配并返回一个新的Vec. rows_itercols_iter试图在一个临时的Vec. 这Vec将在之前释放rows_itercols_iter返回。这意味着Vec必须在函数返回之前释放其上的迭代器。但是,您正试图从函数中返回迭代器,这会使迭代器的寿命比函数的结尾长。

根本没有办法按原样制作rows_itercols_iter编译。我相信这些方法根本没有必要,因为您已经提供了公共rowscols方法。

于 2015-11-29T22:42:14.773 回答