2016-04-05 6 views
0

私はベクトル上のイテレータを関数に渡すパーサを記述しようとしています。コードはこれと似ています:関数に渡されるイテレータの型を書くにはどうすればよいですか?

fn foo(itr : ???) { 
    while let Some(c) = itr.next() { 
     if *c != 0 { 
      break; 
     } 
     println!("{}", *c); 
    } 
} 

fn main() { 
    let v = vec![0; 10]; 
    let itr = v.iter(); 
    while let Some(c) = itr.next() { 
     foo(itr); 
    } 
} 

どのようにベクトルにイテレータのタイプを書くか分かりません。私は間違ったタイプu32を入れてみました。rustcのタイプはcore::slice::Iter<'_, _>です。私はcore::slice rustcがUse of undeclared type or module 'core::slice'

答えて

3

ました。ほとんどの場合、あなたが本当に望んでいるのは、それらのいずれかを消費することができる機能です。これを行うには、慣用的な解決策はジェネリックを使用することです。それはfooitrを移動させるため

fn foo<'a, T: Iterator<Item=&'a i32>>(mut itr: T) { 
    while let Some(c) = itr.next() { 
     if *c != 0 { 
      break; 
     } 
     println!("{}", *c); 
    } 
} 

fn main() { 
    let v = vec![0; 10]; 
    let mut itr = v.iter(); 
    while let Some(c) = itr.next() { 
     foo(itr); 
    } 
} 

上記のコードは、しかしコンパイルしない場合、while letに再び使用しようとします。これを解決するには、イテレータを代わりに参照渡しする必要があります。錆帳からtrait objectsの章では、これらのソリューションの違いを説明

fn foo<'a>(itr: &mut Iterator<Item=&'a i32>) { 
    while let Some(c) = itr.next() { 
     if *c != 0 { 
      break; 
     } 
     println!("{}", *c); 
    } 
} 

fn main() { 
    let v = vec![0; 10]; 
    let mut itr = v.iter(); 
    while let Some(c) = itr.next() { 
     foo(&mut itr); 
    } 
} 

:代わりに、ジェネリック医薬品の

fn foo<'a, T: Iterator<Item=&'a i32>>(itr: &mut T) { 
    while let Some(c) = itr.next() { 
     if *c != 0 { 
      break; 
     } 
     println!("{}", *c); 
    } 
} 

fn main() { 
    let v = vec![0; 10]; 
    let mut itr = v.iter(); 
    while let Some(c) = itr.next() { 
     foo(&mut itr); 
    } 
} 

は、我々はまた、形質オブジェクトを使用することができます。

+0

驚くばかり! FYI再帰的降下構文解析プログラムのような相互に再帰的な関数がある場合、ジェネリックを使用するとrustはコンパイルされませんが、traitオブジェクトを使用すると動作します。 –

0

文句使用しようとするソリューションは、

use std::slice::Iter; 

を追加したとタイプはイテレータの多くの種類があり

fun foo<'a>(itr : &mut Iter<'a, i32>) {} 
+2

これは、 'iter()。map(| x | ...))'ではなく、スライス上の 'iter()'メソッドによって返されるイテレータでのみ関数が使用できることに注意してください。それは別のタイプを持っているからです。 @FrancisGagnéが示唆するように、ここではジェネリックスを使用する必要があります。 –

関連する問題