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