Skip to content

Commit

Permalink
Update iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
XuShaohua committed Jan 7, 2024
1 parent 3ae5310 commit becdab9
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 4 deletions.
5 changes: 4 additions & 1 deletion src/common-traits/any.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ use std::any::{Any, TypeId};
let b: Box<dyn Any> = Box::new(42_i32);
let actual_id = (&*b).type_id();
assert_eq!(actual_id, TypeId::of::<i32>());
```
```

## 相关内容
- [Box Any](../mem/box.md)
7 changes: 6 additions & 1 deletion src/iterator/adapters.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@

# Iterator Adapters
# Iterator Adapters

迭代器可以被串连在一起, 实现更复杂的操作.


## Laziness
44 changes: 44 additions & 0 deletions src/iterator/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,50 @@

# 迭代器 Iterator

迭代器模式, 作为一种常用的设计模式, 在 Rust 里也有广泛的应用.

根据维基百科里的定义, 在面向对象的编程中, 迭代器模式是一种用于遍历容器并访问容器的元素的设计模式.
迭代器模式将算法与容器分离; 在某些情况下, 算法必然是特定于容器的, 因此不能解耦.

`Vec`, `String`, `HashMap` 等标准库里提供的容器, 对迭代器有很完整的支持.
本章我们将介绍与迭代器相关的几个 traits, 以及如何为自定义的类型实现迭代器模式.

## 遍历的三种形式
从一个集合创建迭代器, 有三种形式:

- `iter()`, 通过 `&T` 遍历, 只读的形式
- `iter_mut()`, 通过 `&mut T` 遍历, 可以改变它的值
- `into_iter()`, 通过 `T` 遍历, 发生了所有权的转移

只读引用的形式:
```rust
let v = vec![1, 2, 3, 4];
for x in v.iter() {
println!("{x}");
}
```

可变更引用的形式:
```rust
let mut v = vec![1, 2, 3, 4];
for x in v.iter_mut() {
*x += 1;
}

// 或者使用语法糖
for x in &mut v {
*x += 1;
}
```

发生所有权转移的形式:
```rust
let v = vec![1, 2, 3, 4];
for x in v {
println!("{x}");
}
// v 已经变成未初始化的了, 接下来无法再使用它.
```

## 相关知识
- [Range](../ops/range.md)
28 changes: 27 additions & 1 deletion src/iterator/iterator-into-iterator.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,28 @@

# Iterator 与 IntoIterator
# Iterator 与 IntoIterator

`Iterator` trait 与 `IntoIterator` trait 是 Rust 实现迭代器的基础.

`Iterator` trait 的定义比较复杂, 有70多个方法, 但通常只需要实现 `next()` 方法即可.
该方法会返回 `Option<Self::Item>`, 返回下一个元素 `Some(Self::Item)`; 如果没有下个元素的话, 就返回 `None`.


```rust
pub trait Iterator {
type Item;

// Required method
fn next(&mut self) -> Option<Self::Item>;

// Provided methods
fn next_chunk<const N: usize>(
&mut self
) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where Self: Sized { ... }
fn size_hint(&self) -> (usize, Option<usize>) { ... }
fn count(self) -> usize
where Self: Sized { ... }
fn last(self) -> Option<Self::Item>
where Self: Sized { ... }
...
```
5 changes: 4 additions & 1 deletion src/mem/box.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,7 @@ let x = Box::new(42_i32);
let ptr: *mut i32 = Box::into_raw(x);
let x2 = unsafe { Box::from_raw(ptr) };
assert_eq!(*x2, 42);
```
```

## 相关内容
- [反射 Any](../common-traits/any.md)

0 comments on commit becdab9

Please sign in to comment.