53、Iter

.iter()

 

IntoIterator消耗self来创建一个迭代器。

 

这有它的好处:我们可以从迭代器中获取拥有权的值。例如:如果我们在Vec<Ticket>上调用.into_iter(),我们将会后的返回Ticket的迭代器。

 

这也是它的缺点:在调用.into_iter()后,我们无法再使用原始集合。很多时候,我们希望在不消耗他们的情况下迭代集合,而是查看对值的引用。对于Vec<Ticket>,我们需要迭代&Ticket值。

 

大多数集合都提供了一个名为.iter()的方法,该方法在对集合元素的引用上返回一个迭代器。例如:

let numbers: Vec<u32> = vec![1, 2];
// `n` has type `&u32` here
for n in numbers.iter() {
    // [...]
}

 

这种模式可以通过为集合的引用实现 IntoIterator trait 来简化。在上面的例子中,就是为 &Vec<Ticket> 实现该 trait。

 

标准库可以做到这一点,这就是下面的代码可以正常工作的原因:

let numbers: Vec<u32> = vec![1, 2];
// `n` has type `&u32` here
// We didn't have to call `.iter()` explicitly
// It was enough to use `&numbers` in the `for` loop
for n in &numbers {
    // [...]
}

 

提供这两种选项是惯用的方式:

  • 为集合的引用实现 IntoIterator trait。
  • .iter()方法可以返回对集合引用的迭代器。

 

前者在for循环中使用很方便,后者更加明确,可以用于具体情况。

 

练习

 

这次的练习是:

use ticket_fields::{TicketDescription, TicketTitle};

// TODO: Provide an `iter` method that returns an iterator over `&Ticket` items.
// TODO:提供一个 'iter' 方法,该方法返回 '&Ticket' 项的迭代器。
//
// Hint: just like in the previous exercise, you want to delegate the iteration to
//   the `Vec<Ticket>` field in `TicketStore`. Look at the standard library documentation
//   for `Vec` to find the right type to return from `iter`.
// 提示:与上一题类似,你希望将迭代操作委托给 TicketStore 中的 Vec<Ticket> 字段。
// 请查阅标准库中 Vec 的文档,以确定 iter 方法应返回的正确类型。
#[derive(Clone)]
pub struct TicketStore {
    tickets: Vec<Ticket>,
}

#[derive(Clone, Debug, PartialEq)]
pub struct Ticket {
    title: TicketTitle,
    description: TicketDescription,
    status: Status,
}

impl Ticket {
    pub fn new(title: TicketTitle, description: TicketDescription, status: Status) -> Self {
        Self {
            title,
            description,
            status,
        }
    }
}

#[derive(Clone, Debug, Copy, PartialEq)]
pub enum Status {
    ToDo,
    InProgress,
    Done,
}

impl TicketStore {
    pub fn new() -> Self {
        Self {
            tickets: Vec::new(),
        }
    }

    pub fn add_ticket(&mut self, ticket: Ticket) {
        self.tickets.push(ticket);
    }

   /* TODO */}
}

 

这个iter()就是返回原本数据的引用的迭代器,确保不消费原数据,那么我们要实现这么一个方法,我查了查,没查出来。所以直接看了一下答案:

 

pub fn iter(&self) -> std::slice::Iter<Ticket> {
    self.tickets.iter()
}

这是一个Iter迭代器,迭代器内部的数据是Ticket,selfTicketStore类型,里面有tickets这个vecvec有一个方法是iter,将vec转变为不可变引用迭代器Iter

 

这就清晰明了了,然后函数返回类型是Iter类型。刚搜了一下,这就是Iter的类型定义了吧,就是一个不可变切片迭代器。

 

这一节的内容就先到这里了

 

阅读剩余
THE END