I\'d like to write this:
fn fibs() -> std::iter::Iterator {
return std::iter::iterate((1i, 1i), |(a, b)| { (b, a + b) }).map(|(a, _)| a)
}
as @ChrisMorgan said, for now you can't return an abstract type. If you are creating a public API and want to avoid depending too much on the specific implementation of iterate
and map
, you can encapsulate the return type into your own struct (which is more or less what the collections in the std library themselves do).
Something like:
// updated to rustc 0.13.0-nightly (2015-01-02)
use std::iter::{Map, iterate, Unfold};
type Fibs = Map<(int, int), int, Unfold<(int, int),
(fn((int, int)) -> (int, int), Option<(int, int)>, bool),
fn(&mut (fn((int, int)) -> (int, int), Option<(int, int)>, bool)) ->
Option<(int, int)>>, fn((int, int)) -> int>;
struct Fibs2 {
iter: Fibs,
}
impl Fibs2 {
fn iter() -> Fibs2 {
fn inner((a, b): (int, int)) -> (int, int) { (b, a + b) }
let in_fn = inner as fn((int, int)) -> (int, int);
fn first((a, _): (int, int)) -> int { a }
let p_first = first as fn((int, int)) -> int;
Fibs2{ iter: iterate((1i, 1i), in_fn).map(p_first) }
}
}
impl Iterator<int> for Fibs2 {
fn next(&mut self) -> Option<int> {
self.iter.next()
}
}
fn main() {
for fib_n in Fibs2::iter().take(10) {
println!("{}", fib_n);
}
}
There is not at present any way to return an abstract type such as Iterator<T>
, just as you can’t assign that as the type of a variable (let x: Iterator<uint>;
won’t compile for the same reasons).
This has been discussed and is certainly desired; when it is done it will probably be in the form fn fibs() -> impl Iterator<uint>
, but you can’t do that yet.