@@ -205,3 +205,104 @@ println(fmt!("last: %?", it.next()));
205
205
// the iterator is now fully consumed
206
206
assert!(it.next().is_none());
207
207
~~~
208
+
209
+ ## Conversion
210
+
211
+ Iterators offer generic conversion to containers with the `collect` adaptor:
212
+
213
+ ~~~
214
+ let xs = [ 0, 1, 1, 2, 3, 5, 8] ;
215
+ let ys = xs.rev_iter().skip(1).transform(|&x| x * 2).collect::<~ [ int] >();
216
+ assert_eq!(ys, ~ [ 10, 6, 4, 2, 2, 0] );
217
+ ~~~
218
+
219
+ The method requires a type hint for the container type, if the surrounding code
220
+ does not provide sufficient information.
221
+
222
+ Containers can provide conversion from iterators through `collect` by
223
+ implementing the `FromIterator` trait. For example, the implementation for
224
+ vectors is as follows:
225
+
226
+ ~~~
227
+ impl<A, T: Iterator<A >> FromIterator<A, T> for ~ [ A] {
228
+ pub fn from_iterator(iterator: &mut T) -> ~ [ A] {
229
+ let (lower, _ ) = iterator.size_hint();
230
+ let mut xs = with_capacity(lower);
231
+ for iterator.advance |x| {
232
+ xs.push(x);
233
+ }
234
+ xs
235
+ }
236
+ }
237
+ ~~~
238
+
239
+ ### Size hints
240
+
241
+ The `Iterator` trait provides a `size_hint` default method, returning a lower
242
+ bound and optionally on upper bound on the length of the iterator:
243
+
244
+ ~~~
245
+ fn size_hint(&self) -> (uint, Option<uint >) { (0, None) }
246
+ ~~~
247
+
248
+ The vector implementation of `FromIterator` from above uses the lower bound
249
+ to pre-allocate enough space to hold the minimum number of elements the
250
+ iterator will yield.
251
+
252
+ The default implementation is always correct, but it should be overridden if
253
+ the iterator can provide better information.
254
+
255
+ The `ZeroStream` from earlier can provide an exact lower and upper bound:
256
+
257
+ ~~~
258
+ /// A stream of N zeroes
259
+ struct ZeroStream {
260
+ priv remaining: uint
261
+ }
262
+
263
+ impl ZeroStream {
264
+ fn new(n: uint) -> ZeroStream {
265
+ ZeroStream { remaining: n }
266
+ }
267
+
268
+ fn size_hint(&self) -> (uint, Option<uint>) {
269
+ (self.remaining, Some(self.remaining))
270
+ }
271
+ }
272
+
273
+ impl Iterator<int > for ZeroStream {
274
+ fn next(&mut self) -> Option<int > {
275
+ if self.remaining == 0 {
276
+ None
277
+ } else {
278
+ self.remaining -= 1;
279
+ Some(0)
280
+ }
281
+ }
282
+ }
283
+ ~~~
284
+
285
+ ## Double-ended iterators
286
+
287
+ The `DoubleEndedIterator` trait represents an iterator able to yield elements
288
+ from either end of a range. It inherits from the `Iterator` trait and extends
289
+ it with the `next_back` function.
290
+
291
+ A `DoubleEndedIterator` can be flipped with the `invert` adaptor, returning
292
+ another `DoubleEndedIterator` with `next` and `next_back` exchanged.
293
+
294
+ ~~~
295
+ let xs = [ 1, 2, 3, 4, 5, 6] ;
296
+ let mut it = xs.iter();
297
+ println(fmt!("%?", it.next())); // prints ` Some(&1) `
298
+ println(fmt!("%?", it.next())); // prints ` Some(&2) `
299
+ println(fmt!("%?", it.next_back())); // prints ` Some(&6) `
300
+
301
+ // prints ` 5 ` , ` 4 ` and ` 3 `
302
+ for it.invert().advance |&x| {
303
+ println(fmt!("%?", x))
304
+ }
305
+ ~~~
306
+
307
+ The `rev_iter` and `mut_rev_iter` methods on vectors just return an inverted
308
+ version of the standard immutable and mutable vector iterators.
0 commit comments