2014-10-12 6 views
6

mi piacerebbe scrivere questo:Tornando un'interfaccia Iterator più semplice invece di una mappa a Rust

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

Ma se lo faccio, ottengo questo errore:

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

Se, invece ho scrivere l'interfaccia completa, compila:

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

C'è un modo per restituire l'interfaccia più semplice?

+0

Iterator è una caratteristica e non un tipo. Non so molto di Rust, ma penso che tu abbia bisogno di metterlo nella scatola. Per restituire i tipi astratti non archiviati abbiamo bisogno di questo: https://github.com/rust-lang/rfcs/pull/105 – Simon

risposta

6

Non esiste attualmente alcun modo per restituire un tipo astratto come Iterator<T>, così come non è possibile assegnarlo come tipo di variabile (let x: Iterator<uint>; non verrà compilato per gli stessi motivi).

Questo has been discussed ed è sicuramente desiderato; quando è fatto, probabilmente sarà nella forma fn fibs() -> impl Iterator<uint>, ma non è ancora possibile farlo.

+0

Sembra che il problema sia stato chiuso: https://github.com/rust-lang/rfcs/ tirare/105. La RFC è sostituita da un'altra? –

+0

Non credo che sia stato per il momento, ma lo sarà ad un certo punto. –

+0

Buone notizie, ce n'è una nuova: https://github.com/rust-lang/rfcs/issues/518 –

1

come ha detto @ChrisMorgan, per ora non è possibile restituire un tipo astratto. Se si sta creando un'API pubblica e si desidera evitare di dipendere troppo dall'implementazione specifica di iterate e map, è possibile incapsulare il tipo restituito nella propria struct (che è più o meno ciò che fanno le raccolte nella stessa libreria std).

Qualcosa di simile:

// 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

Grazie! Penso che Swift faccia lo stesso genere di cose ma genericamente con AnySequence https://developer.apple.com/library/tvos/documentation/Swift/Reference/Swift_AnySequence_Structure/index.html –

Problemi correlati