はじめに
はじめまして、task4233です。
これはあくまでメモなので、基本的にググってわかるようなことは詳しく書きません。
よろしくお願いします。
なお、以下のプログラムでは面倒なのでfn main() {}
を省略することがあります。
ご承知おきください。
おさらい
前回は4章の4.3-4.4に目を通して、以下のことを学びました。
- プリミティブ型の種類と基本的な使用法
- コメントの種類とその活用法
以下のリンクで参照できます。
https://qiita.com/task4233/items/50b536e42b0ad0cc7589
4. シンタックスとセマンティクス
Rustをボトムアップで学びたいなら、この章を順番に読んでいくのが近道です。
だそうです。
4.5. if
Rustにおけるif文の使い方を知り、扱えるようになること。
if
メモなので深くは書きません。
書き方の例のみ残しておきます。
let x = 5; // x: i32
if x == 5 {
println!("x is 5.");
} else if x == 6 {
println!("x is 6.");
} else {
println!("x is not (5 or 6).");
}
さらに代入として、以下のようにも書けます。
let x = 5; // x: i32
let y = if x == 5 { 10 } else { 15 }; // y: i32
let z = if x == 6 { 10 }; // z: i32 // elseのないifでは()が返されるのでコンパイルエラー
println!("{}", x); // 5
println!("{}", x); // 10
シャドーイングにより、異なる型の再束縛も可能。
let x = 5; // x: i32
let y = if x == 5 { 10.5 } else { 15.5 }; // y: i32
let z = if x == 5 { 10.5 } else { 15 } // 型が統一されていないのでコンパイルエラー
println!("{}", x); // 5
println!("{}", y); // 10.5
}
基本的には他の言語と同じような扱いです。
ただし、返り値を意識して書かないとエラーが出ます。
4.6. ループ
Rustの3種類のループを知り、基本的な使用ができるようになること。
Rustにはループとして、loop
, while
, for
の3種類があります。
順を追って説明します。
loop
loop
は無限ループをします。
何らかの終了状態に到達するまで永遠とループし続ける手段を提供します。
以下のコードはloop
を利用して8回だけループします。
fn main() {
let mut i: i32 = 0;
loop {
if i == 8 { return; }
println!("count is: {}", i);
i = i + 1;
}
}
/* [output]
count is: 0
count is: 1
count is: 2
count is: 3
count is: 4
count is: 5
count is: 6
count is: 7
*/
while
他の言語でも存在しているので、軽く書きます。
以下は、初項8で公差3の数列について、5で割り切れた時にループを抜けるコードです。
let mut i = 5; // mut x:i32
let mut done = false; // mut done: bool
while !done {
x += 3;
println!("{}", x);
if x % 5 == 0 {
done = true;
}
}
/*
[output]
8
11
14
17
20
*/
for
Rustのforループは以下のように書きます。
ここで、ループする変数はlet mut
などと宣言する必要はありません。
for x in 0..10 {
println!("{}", x); //x: i32
}
/*
[output]
0
1
2
3
4
5
6
7
8
9
*/
}
以上の3種類のループにおいて、
while true:
のようなループを書きたい時はloop
、
特定の条件を満たしている時に反復したい時はwhile
、
特定の範囲でループをしたい時はfor
を使うと良いと思います。
ただし、速度でいうとwhile
基本的にはfor
を使用するのが安全な気がします。
オーダも安定しますしね。
列挙
ループの中で何回めの繰り返しかを把握するときには、以下のように.enumerate()
関数を利用できます。
レンジ(5..10)
を括弧で括ることを忘れないように注意。
for (i, j) in (5..10).rnumerate() {
println!("i = {} and j = {}", i, j);
}
/*
[output]
i = 0 and j = 5
i = 1 and j = 6
i = 2 and j = 7
i = 3 and j = 8
i = 4 and j = 9
*/
イテレータを対象に列挙
.lines()
を使用して行ごとに分けたものについても、以下のように列挙可能です。
let lines = "hello\nworld".lines();
for (linenumber, line) in lines.enumerate() {
println!("{}: {}", linenumber, line);
}
/*
[output]
0: hello
1: world
*/
反復の早期終了
他言語でも使用されているbreak
およびcontinue
です。
説明は割愛します。
ループラベル
先ほどのbreak
およびcontinue
について、飛ぶ先を指定します。
以下のコードはx
が偶数の時のみ表示します。
'outer: for x in 0..10 {
if x % 2 == 1 {continue 'outer; }
println!("x: {}", x);
}
}
/*
[output]
x: 0
x: 2
x: 4
x: 6
x: 8
Rustにおけるループは、
・loop
・while
・for
の3種類。
loopとwhileは無限ループになりやすいため、しっかりと条件を設定すること。
おわりに
4章4.5-4.6では大まかに以下の2つが書かれていました。
- if-else, else ifの使い方とその仕様
- loop, while, forの3種類のループとそのオプション
無限ループは恐ろしいので、loop
はあまり使いたくないです……
loop
は結局のところ条件で抜けるので、while
で十分であると考えます。
さきほどscivolaさんにお教えいただいたのですが、Rustドキュメントの2版がリリースされていたようです……
Web版: https://doc.rust-jp.rs/book/second-edition/
PDF版: https://y-yu.github.io/trpl-2nd-pdf/book.pdf
明らかにそちらのドキュメントの方が分かりやすいので、メモを書く意義を見失いかけています……
今後のメモは書くことが少なくなるかもしれません……
とにかく次は、所有権、参照と借用を見ようと思います。