今回からイテレータに入りました。前回、NoneとSome、そしてanyを「予習」しておいたおかげで多少は分かりやすかったんでないかい。でも今回は分かりやすい奴ら(メソッド)ばかり練習してみたから当たり前か。なんだかね、とってもいろいろいるのよね、よくわからない奴らが。<訂正あり
※2022年11月28日訂正: (1.10)をstd::iterのごとくに使用してますが、(1..10)はstd::ops::Range でした。共通するお名前で同様な機能のTraitsが実装されているのでイテレータではないのにイテレータとして練習してしまいました。以下コード中 (1..10)の代わりに[1, 2, 3, 4, 5, 6, 7, 8, 9].iter()とすれば「正式な」イテレータになるんでないの、と思われます。
※「やっつけな日常」投稿順 Index はこちら
VScodeで cargoで作ったrustのプロジェクトを開き、”(1..2).” と “.”(ピリオド)を打ったら冒頭のアイキャッチ画像のごとく、大量の補完候補が提示されました。みんなIterator一族のメソッドの方々。画像には a から c で始まるメソッドしか表示されていませんから、全体数はとんでもない数みたいです。
しかしま、Iterator一族を使えるようにしないとRustの「繰り返し」は分からないままなのでちゃんとやらないと。全貌は以下のドキュメントに書かれてます。
ただね、上記のドキュメントでは以下のように experimental APIなどと書かれているものが結構あります。元来保守派なので、そいつらはとりあえずパス、先に簡単な奴らから(手抜き。)
今回練習してみたメソッド
今回使ってみたのは、戻り値が簡単な以下の奴らです。
-
- 真偽値を返すもの。all, any, eq, ge。
- 整数値を返すもの。count
- 前回登場の列挙型、Optionを返すもの。find、last、max, min, nth, potion
1は、geがあれば、leとかgtとかありがちな奴らは皆いるのですが、流石に疲れるので、eqとgeだけやりました。anyは前回も登場。どれもtrueかfalseを返すものどもです。allとanyは前々回やったクロージャを引数に与えて判定を迫る?もの。eqやgeは、イテレータ自体を比較?しているような構文です。
2は、Iteratorが返してくるItemの数を返すもの。ちょいと疑問があるのですが今回はそこには突っ込まず。
3は、前回登場の列挙型Optionを返すもの。前回やったNoneとSomeが返ってくる奴らです。findとpositionはクロージャを引数にとり、nthは整数をとりますが、last、max、minは無しでよろしいと。
実験に使ったソースコードは以下に。イテレータとしては1から10までのrangeをすべてに与えてみています。
fn main() { //all println!("all(<11): {}", (1..10).all(|x| x<11)); println!("all(>5): {}", (1..10).all(|x| x>5)); //any println!("any(x==5): {}", (1..10).any(|x| x == 5)); println!("any(x=11): {}", (1..10).any(|x| x > 10)); //eq println!("eq: {}", (1..10).eq(1..10)); //ge println!("ge(1..9): {}", (1..10).ge(1..9)); println!("ge(1..10): {}", (1..10).ge(1..10)); println!("ge(1..11): {}", (1..10).ge(1..11)); //count println!("count: {}", (1..10).count()); //find match (1..10).find(|x| x == &4) { None => println!("None"), Some(dat) => println!("find(x==4): {}", dat), } //last match (1..10).last() { None => println!("None"), Some(dat) => println!("last: {}", dat), } //max match (1..10).max() { None => println!("None"), Some(dat) => println!("max: {}", dat), } //min match (1..10).min() { None => println!("None"), Some(dat) => println!("min: {}", dat), } //nth match (1..10).nth(5) { None => println!("None"), Some(dat) => println!("nth(5): {}", dat), } match (1..10).nth(10) { None => println!("nth(10): None"), Some(dat) => println!("nth(10): {}", dat), } //position match (1..10).position(|x| x == 7) { None => println!("None"), Some(dat) => println!("position(7): {}", dat), } }
実機での実行結果
実機での実行結果が以下に。一応予定どおりでないかい。
上みると5番目は6,7になるのは6番目ってことだね。0番目始まり。また、1..10であって、1..=10でないので lastは9、maxも9。countの数も9。
この辺の簡単な奴らの挙動は分かった。あたりまえか。