2014-10-12 8 views
6

Ich möchte, dies schreiben:Rückkehr eine einfachere Iterator-Schnittstelle statt einer Karte in Rust

fn fibs() -> std::iter::Iterator<int> { 
    return std::iter::iterate((1i, 1i), |(a, b)| { (b, a + b) }).map(|(a, _)| a) 
} 

Aber wenn ich es tue, bekomme ich diesen Fehler:

error: explicit lifetime bound required 
fn fibs() -> std::iter::Iterator<int> { 
      ^^^^^^^^^^^^^^^^^^^^^^^^ 

Wenn stattdessen I schreibe die vollständige Schnittstelle aus, es kompiliert:

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) 
} 

Gibt es eine Möglichkeit, die einfachere Schnittstelle zurückzugeben?

+0

Iterator ist ein Merkmal und kein Typ. Ich weiß nicht viel über Rust, aber ich denke, du musst es in Box packen. Um ungepackte abstrakte Typen zurückzugeben, benötigen wir diese: https://github.com/rust-lang/rfcs/pull/105 – Simon

Antwort

6

Es gibt derzeit keine Möglichkeit, einen abstrakten Typ wie Iterator<T> zurückzugeben, genauso wie Sie das nicht als Typ einer Variablen zuweisen können (let x: Iterator<uint>; wird aus den gleichen Gründen nicht kompiliert).

Diese has been discussed und ist sicherlich erwünscht; wenn es fertig ist, wird es wahrscheinlich in der Form fn fibs() -> impl Iterator<uint> sein, aber Sie können das noch nicht tun.

+0

Es scheint, dass das Problem geschlossen wurde: https://github.com/rust-lang/rfcs/ ziehen/105. Wird der RFC durch einen anderen ersetzt? –

+0

Ich glaube nicht, dass es für den Moment gewesen ist, aber es wird irgendwann sein. –

+0

Gute Nachrichten, es gibt eine neue: https://github.com/rust-lang/rfcs/issues/518 –

1

wie @ ChrisMorgan sagte, für jetzt können Sie nicht eine abstrakte Art zurückgeben. Wenn Sie eine öffentliche API erstellen und nicht zu sehr auf die spezifische Implementierung von iterate und map angewiesen sein möchten, können Sie den Rückgabetyp in Ihre eigene Struktur kapseln (was mehr oder weniger der Inhalt der Sammlungen in der Standardbibliothek ist).

Etwas wie:

// 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); 
    } 
} 
+0

Danke! Ich denke Swift macht die gleiche Sache, aber generisch mit AnySequence https://developer.apple.com/library/tvos/documentation/Swift/Reference/Swift_AnySequence_Structure/index.html –