関数は、1つ以上の文や式を含むコードのまとまりです。関数は、任意で戻り値を返すことができます。
Rustでは、関数名にスネークケースを使うのがスタイルです。関数を定義するときは、名前の前にfnキーワードを付けます。たとえば、
fn do_nothing() {}
括弧(())は、カンマで区切られた0個以上の仮引数を囲みます。仮引数は、関数に渡される特定の型の値への束縛です。仮引数がなくても、関数の定義には括弧が必要です。仮引数に渡される実際の値は、引数と呼ばれます。
仮引数と戻り値を合わせたものは、関数のシグネチャと呼ばれます。関数のシグネチャでは、それぞれの仮引数に型注釈を付ける必要があります。
波括弧({})は、関数の本体、つまり文や式を囲みます。関数に文や式が含まれていなくても、関数の定義には波括弧が必要です。
次の例では、関数はi32型の仮引数を1つ受け取り、それをvalueという名前に束縛して、出力します。
fn print_integer(value: i32) {
println!("{value:?}");
}
仮引数の定義に注目してください。各仮引数はname: Typeという形式で定義します。
関数は値を返すこともできます。デフォルトでは、最後の式の出力が戻り値になります。次の例では、関数はi32の仮引数を1つ持ち、その2倍を返します。
fn double_integer(value: i32) -> i32 {
value * 2
}
-> i32は、関数がi32を返すことを示します。仮引数とは異なり、戻り値には名前がありません。
returnキーワードを使うと、関数から途中で抜けることができます。次のようになります。
fn long_function() -> i32 {
let some_condition = false;
// code snipped
if (some_condition) {
return 0;
}
// more code snipped
42
}
const fnは定数関数を定義するために使われ、コンパイル時に評価できます。
const fn compute_data_checksum() -> u128 {
const DATA: &[u8] = include_bytes!("my_big_data_file");
// checksum implementation is left as an exercise for the reader
}
/// This checksum is used to validate that the user has not tampered with proprietary configuration.
pub const DATA_CHECKSUM: u128 = compute_data_checksum();
定数関数はコンパイル時に評価されることがあるため、通常の関数にはないいくつかの制約があります。特に、const fnはconstが付いた他の関数しか呼び出せません。この制約に従わないと、コンパイルエラーになります。
const fn multiply_integer(value: i32) -> i32 {
use std::time::SystemTime;
if SystemTime::now().elapsed().unwrap().as_nanos() == 0 { // this line errors
value * 2
} else {
value * 3
}
}
匿名関数もあります。これについてはclosuresのトピックで扱います。