前回からだいぶ間が空いてしまいましたが、Rustの勉強を続けていきたいと思います。ちなみに言い訳をしておきますが、9月前半が予定が立て込んでであまり更新できなかっただけで別に飽きたわけではないです。
…飽きたわけではないです。大事なことなので2回。
前置き
この記事はまだRustをよく知らない人が勉強しながら書いているので、もしかしたら間違ったことが書いてあるかもしれません。ご了承ください。
参考文献
The Rust Programming Language 日本語版
関数
fn show_message() {
println!("Hello World!");
}
fn main() {
show_message();
}
Hello World!
基本的にはC++と同じ。Rustの命名規則では、関数と変数はスネークケース(show_messageやload_dataなど)を使うのが慣例だそうです。ちなみに、
fn main() {
show_message();
}
fn show_message() {
println!("Hello World!");
}
このように、呼び出す関数が後ろに定義されていてもOK。C++は呼び出す前に関数を定義しなければならなかったので便利ですね。
引数を使う
当然ながら関数に引数を使うこともできます。
fn show_figures(x: i32, y: i32) {
println!("x={}, y={}", x, y);
}
fn main() {
show_figures(100, 200);
}
x=100, y=200
show_figuresのxとyを仮引数といいますが、仮引数を宣言する際は型宣言が必要だそうです。つまり、整数であればx: i32
やx: i64
などと仮引数の型を明確に定義しなければなりません。
値を返す
Rustでは、何らかの値を返す関数を式、何の値も返さない関数を文と分類します。さきほどのshow_message
やshow_figure
は文です。
今度は値を返す関数である式を作成してみます。
fn kakeru_100(x: i32) -> i32 {
x * 100
}
fn main() {
let x = kakeru_100(123);
println!("x={}", x);
}
x=12300
kakeru_100
は仮引数に対し100を掛けた値を返す関数です。-> i32
によって返り値の型を指定しています。main関数では、xに引数を123としたkakeru_100
の値を代入します。ここで重要なのは、Rustではセミコロン;
がない式が返り値として識別されるという点です。
フロー制御
フロー制御とは何かというと、if文とかループとかですね。与えられた変数の条件によって{}の中身を実行するか否かが変化する、条件分岐を伴う処理のことです。
if文
Rustのif文はC++みたいに()でくくる必要はありません。なんだかHSP3を思い出します。
fn main() {
let x = 100;
if x == 50 {
println!("x is 50");
} else {
println!("x is not 50");
}
}
x is not 50
let文内のif文
if文は式であるため、こんな使い方もできます。
fn main() {
let a = true;
let num = if a {
1
} else {
0
};
println!("num == {}", num);
}
num == 1
上記のプログラムでは、変数numと数値を束縛する際に、aがtrueなら1、falseなら0を束縛します。
繰り返し
繰り返し処理には3種類も存在するらしいです。loop
とfor
とwhile
です。
loop
for
とwhile
は想像がつきますが、loop
は何かというと、要は無限ループです。
fn main() {
loop {
println!("無限ループって怖くね?");
}
}
無限ループって怖くね?
無限ループって怖くね?
無限ループって怖くね?
無限ループって怖くね?
︙
上記のプログラムではControl+Cで中断させない限り永遠に表示され続けます。break
を使えば中断させることができますが、それだったらwhile
でよくね?って気もします。
while
おなじみ条件付きループ。使い方も今まで触ってきた言語と変わってなくて安心します。
fn main() {
let mut count = 5;
while count >= 0 {
println!("{}", count);
count -= 1;
}
println!("done.");
}
5
4
3
2
1
0
done.
for
こちらもおなじみ。変数宣言もfor文内で行えます。Range型を使うと、a..b
でaからb-1までカウントしてくれます。
fn main() {
for i in 1..11 {
println!("{}", i);
}
println!("done.");
}
1
2
3
4
5
6
7
8
9
10
done.
a..=b
とすれば、aからbまでの間をカウントしてくれます。
fn main() {
for i in 1..=11 {
println!("{}", i);
}
println!("done.");
}
1
2
3
4
5
6
7
8
9
10
11
done.
逆順にするにはrev
を使います。
fn main() {
for i in (1..=11).rev() {
println!("{}", i);
}
println!("done.");
}
11
10
9
8
7
6
5
4
3
2
1
done.
C++やPythonと同様に配列を順に参照することもできます。
fn main() {
let array = [3, 6, 9, 12];
for element in array {
println!("{}", element);
}
println!("done.");
}
3
6
9
12
done.
FizzBuzz
せっかくなのでRustでFizzBuzzを作ってみました。プログラミングの入門書によく出てくる、3の倍数なら「Fizz」5の倍数なら「Buzz」と出力するアレです。
関数fizz_buzzを作成し、1から引数に指定した数までカウントアップさせています。
fn fizz_buzz(x: i32) {
for i in 1..=x {
if i % 15 == 0 {
print!("FizzBuzz");
} else if i % 3 == 0 {
print!("Fizz");
} else if i % 5 == 0 {
print!("Buzz");
} else {
print!("{} ", i);
}
println!();
}
}
fn main() {
fizz_buzz(20);
}
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
終わりに
所有権や可変性のように独特な縛りは多いものの、今までの言語で「あったらいいな」と思っていたものが実装されていたり、少しづつRustの魅力が理解できるようになってきた気がします。
基本的にThe Rust Programming Languageに沿って進めています。今回は簡単な内容でしたが、どうやら次回は難しそうです。近日中に進めたいと思います。