やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

Rustでくりかえし文(for)

 イテレート。for in文。なんとカウンタ式のfor文は使えない。

成果物

ソースコード

use std::ops::Range;

fn main() {
//    let mut x = 0;
//    for (x = 0; x < 10; x++) {
//        println!("for {}", x);
//    }
    for x in 0..10 {
        println!("for {}", x);
    }
    for x in (0..10).rev() { println!("for {}", x); }
//    for x in 9..-1 { println!("for {}", x); }

    let array = [1, 3, 5];
    for v in array.iter() { println!("array {}", v); }

    let names = vec!["Bob", "Frank", "Ferris"];
    for name in names.iter() { println!("{}", name); }

    for x in get_ten() { println!("for {}", x); }
}
//fn get_ten() { 0..10 } // error[E0308]: mismatched types    std::ops::Range
//fn get_ten() -> i32 { 0..10 } // error[E0308]: mismatched types    std::ops::Range
//fn get_ten() -> std::ops::Range { 0..10 } // error[E0107]: wrong number of type arguments: expected 1, found 0
//fn get_ten() -> Range { 0..10 } // error[E0107]: wrong number of type arguments: expected 1, found 0
fn get_ten() -> Range<i32> { 0..10 } 
  • for 値 in イテレータ { ... }文を使う
  • 配列, vec, Range型で動作を確認した

実行

$ rustc main.rs
$ ./main
for 0
for 1
for 2
for 3
for 4
for 5
for 6
for 7
for 8
for 9
for 9
for 8
for 7
for 6
for 5
for 4
for 3
for 2
for 1
for 0
array 1
array 3
array 5
Bob
Frank
Ferris
for 0
for 1
for 2
for 3
for 4
for 5
for 6
for 7
for 8
for 9

固定範囲

fn main() {
    for x in 0..10 {
        println!("for {}", x);
    }

 0以上10未満まで。つまり09。え、10までじゃないの? わかりづいらい。あと、?..?の構文、名前は? ググれない……。

固定範囲(逆順)

fn main() {
    for x in (0..10).rev() { println!("for {}", x); }

 (0..10)というリテラルは何らかのオブジェクトっぽい。rev()メソッドを持っている。おそらくreverseの略と思われる。[0, 1, 2, ..., 9]の配列? から新たに[9, 8, 7, ..., 0]の配列を生成していると思われる。

配列

fn main() {
    let array = [1, 3, 5];
    for v in array.iter() { println!("array {}", v); }
}

 配列オブジェクトからイテレータを取得することでループ。

配列(逆順)

use std::ops::Range;

fn main() {
//    let mut x = 0;
//    for (x = 0; x < 10; x++) {
//        println!("for {}", x);
//    }
    for x in 0..10 {
        println!("for {}", x);
    }
    for x in (0..10).rev() { println!("for {}", x); }
//    for x in 9..-1 { println!("for {}", x); }

    let array = [1, 3, 5];
    for v in array.iter() { println!("array {}", v); }

    let names = vec!["Bob", "Frank", "Ferris"];
    for name in names.iter() { println!("{}", name); }

    for x in get_ten() { println!("for {}", x); }
}
//fn get_ten() { 0..10 } // error[E0308]: mismatched types    std::ops::Range
//fn get_ten() -> i32 { 0..10 } // error[E0308]: mismatched types    std::ops::Range
//fn get_ten() -> std::ops::Range { 0..10 } // error[E0107]: wrong number of type arguments: expected 1, found 0
//fn get_ten() -> Range { 0..10 } // error[E0107]: wrong number of type arguments: expected 1, found 0
fn get_ten() -> Range<i32> { 0..10 } 

vec

fn main() {
    let names = vec!["Bob", "Frank", "Ferris"];
    for name in names.iter() { println!("{}", name); }
}

 ベクタはコレクションのひとつ。配列に似ているが、要素数が可変にできる。

Range

use std::ops::Range;
fn main() {
    for x in get_ten() { println!("for {}", x); }
}
fn get_ten() -> Range<i32> { 0..10 } 

 Range型。

 0..10を返す関数でループしたらどうなるか試した。Range型なんて知らなかったが、何度もエラーしまくっているうちにコードが書けてしまった。親切なエラーメッセージのおかげ。

yield

fn get_seven() { yield 7 } 
error[E0658]: yield syntax is experimental (see issue #43122)

yield構文は実験的です

 ならまだ勉強しなくていいや。

エラー

カウンタ

 C言語風のfor文が書けない。

fn main() {
    let mut x = 0;
    for (x = 0; x < 10; x++) {
        println!("for {}", x);
    }
}
error: expected one of `)`, `,`, or `@`, found `=`
 --> main.rs:7:12
  |
7 |     for (x = 0; x < 10; x++) {
  |            ^ expected one of `)`, `,`, or `@` here

error: aborting due to previous error

参考

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux

前回まで