I'd like to write this:
fn fibs() -> std::iter::Iterator<int> {
return std::iter::iterate((1i, 1i), |(a, b)| { (b, a + b) }).map(|(a, _)| a)
}
But if I do, I get this error:
error: explicit lifetime bound required
fn fibs() -> std::iter::Iterator<int> {
^^^^^^^^^^^^^^^^^^^^^^^^
If, instead I write out the full interface, it compiles:
fn fibs() -> std::iter::Map<'static, (int, int), int, std::iter::Iterate<'static, (int, int)>> {
return std::iter::iterate((1i, 1i), |(a, b)| { (b, a + b) }).map(|(a, _)| a)
}
Is there a way to return the simpler interface?
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.
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With