Rust入門シリーズの第4回です。関数はロジックに名前を付け、再利用するための方法です。Rustの関数はシンプルです — 核となる考えは、ほぼすべてが式だということです。
最初の関数#
fn add(a: i32, b: i32) -> i32 {
a + b
}
fn main() {
let result = add(3, 4);
println!("{result}"); // 7
}rustパラメータは型を宣言し、戻り値の型は->の後に置きます。
ステートメントと式#
ステートメントは動作を実行し、何も返しません。式は値を評価します。
fn add(a: i32, b: i32) -> i32 {
let sum = a + b; // ステートメント、セミコロンで終わる
sum // 式、セミコロンなし
}rust最後の式 — セミコロンなし — が戻り値になります。セミコロンを付けると、関数は代わりに()を返します。
早期リターン#
returnで早期に抜けます:
fn is_adult(age: u32) -> bool {
if age >= 18 {
return true;
}
false
}rust戻り値がない関数#
何も返さない関数はユニット型()を持ちます:
fn greet(name: &str) {
println!("Hello, {name}!");
}rust暗黙の戻り値の型は()です。
所有権の受け渡し#
デフォルトでは、値を関数に渡すと移動します(詳細は次回の所有権の記事):
fn print_len(s: String) {
println!("{}", s.len());
}
fn main() {
let s = String::from("hello");
print_len(s); // sが移動される
// println!("{s}"); // エラー: sはもう存在しない
}rustジェネリック関数#
関数は山括弧を使って型に対してジェネリックにできます:
fn first<T>(list: &[T]) -> &T {
&list[0]
}rustTは任意の型を表します。コンパイラが呼び出し箇所から推論します。
結論#
Rustの関数はどこまでも式です。パラメータは型付けされ、最後の式が戻り値になり、所有権は値とともに移動します。シリーズ次回は所有権です。