Skip to content

Commit b64a03c

Browse files
committed
more iteration traits
1 parent a2ff6b0 commit b64a03c

File tree

1 file changed

+86
-1
lines changed

1 file changed

+86
-1
lines changed

posts/tour-of-rusts-standard-library-traits.md

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ _31 March 2021 · #rust · #traits_
5757
- [ToOwned](#toowned)
5858
- [Iteration Traits](#iteration-traits)
5959
- [Iterator](#iterator)
60+
- [ExactSizeIterator](#exactsizeiterator)
6061
- [IntoIterator](#intoiterator)
62+
- [Extend](#extend)
6163
- [FromIterator](#fromiterator)
6264
- [I/O Traits](#io-traits)
6365
- [Read & Write](#read--write)
@@ -4896,17 +4898,70 @@ for v in (&mut vec).into_iter() {}
48964898

48974899

48984900

4901+
### Extend
4902+
4903+
Prerequisites
4904+
- [Self](#self)
4905+
- [Methods](#methods)
4906+
- [Generic Parameters](#generic-parameters)
4907+
- [Iterator](#iterator)
4908+
- [IntoIterator](#intoiterator)
4909+
4910+
4911+
```rust
4912+
trait Extend<A> {
4913+
fn extend<T>(&mut self, iter: T)
4914+
where T: IntoIterator<Item = A>;
4915+
4916+
// provided default impls
4917+
fn extend_one(&mut self, item: A);
4918+
fn extend_reserve(&mut self, additional: usize);
4919+
}
4920+
```
4921+
4922+
`Extend` types can be extended from an iterator. They're usually collections. Using `MyType` from before:
4923+
4924+
```rust
4925+
struct MyType {
4926+
items: Vec<String>
4927+
}
4928+
4929+
impl Extend<String> for MyType {
4930+
// add Strings from iter into MyType
4931+
fn extend<T: IntoIterator<Item = String>>(&mut self, iter: T) {
4932+
for i in iter {
4933+
self.items.push(i);
4934+
}
4935+
}
4936+
}
4937+
```
4938+
4939+
The above example is meant to be illustrative, the idiomatic solution would be to defer to the inner `Vec`'s `extend` impl:
4940+
4941+
```rust
4942+
impl Extend<String> for MyType {
4943+
// add Strings from iter into MyType
4944+
fn extend<T: IntoIterator<Item = String>>(&mut self, iter: T) {
4945+
self.items.extend(iter)
4946+
}
4947+
}
4948+
```
4949+
4950+
4951+
48994952
### FromIterator
49004953

49014954
Prerequisites
49024955
- [Self](#self)
49034956
- [Functions](#functions)
49044957
- [Generic Parameters](#generic-parameters)
4958+
- [Sized](#sized)
49054959
- [Iterator](#iterator)
49064960
- [IntoIterator](#intoiterator)
4961+
- [Extend](#extend)
49074962

49084963
```rust
4909-
trait FromIterator<A> {
4964+
trait FromIterator<A>: Sized {
49104965
fn from_iter<T>(iter: T) -> Self
49114966
where
49124967
T: IntoIterator<Item = A>;
@@ -4952,6 +5007,36 @@ fn entry_list<K, V>(map: HashMap<K, V>) -> LinkedList<(K, V)> {
49525007
// and countless more possible examples
49535008
```
49545009

5010+
If we're going to impl `FromIterator` for our own type its best to reuse an `Extend` impl if one exists:
5011+
5012+
```rust
5013+
struct MyType {
5014+
items: Vec<String>,
5015+
}
5016+
5017+
impl MyType {
5018+
fn new() -> Self {
5019+
MyType {
5020+
items: Vec::new()
5021+
}
5022+
}
5023+
}
5024+
5025+
impl Extend<String> for MyType {
5026+
fn extend<T: IntoIterator<Item = String>>(&mut self, iter: T) {
5027+
self.items.extend(iter)
5028+
}
5029+
}
5030+
5031+
impl FromIterator<String> for MyType {
5032+
fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
5033+
let mut my_type = MyType::new();
5034+
my_type.extend(iter);
5035+
my_type
5036+
}
5037+
}
5038+
```
5039+
49555040

49565041

49575042
## I/O Traits

0 commit comments

Comments
 (0)