Rustの関数
関数(function)は、名前を付けて何度でも使えるようにしたコードのかたまりです。同じ手順を何度も書く代わりに、一度関数にまとめておけば、必要なときにいつでも呼び出せます。実は、もうすでに1つ使っています。main です。
関数を定義して呼び出す
Section titled “関数を定義して呼び出す”関数は fn で定義し、名前の後ろに () を付けて呼び出します。
fn greet() { println!("関数からこんにちは!");}
fn main() { greet(); // 呼び出す greet(); // もう一度呼び出す}実行結果:
関数からこんにちは!関数からこんにちは!引数:関数にデータを渡す
Section titled “引数:関数にデータを渡す”関数は、処理するデータを渡せるようになると一気に便利になります。この入力を引数(パラメータ)と呼びます。Rustでは、引数にはそれぞれ型を必ず書かなければなりません。
fn greet(name: &str) { println!("こんにちは、{name}さん!");}
fn main() { greet("アリス"); greet("ボブ");}実行結果:
こんにちは、アリスさん!こんにちは、ボブさん!引数は、カンマで区切っていくつでも書けます。
fn describe(name: &str, age: u32) { println!("{name}は{age}歳です");}
fn main() { describe("Ferris", 10);}実行結果:
Ferrisは10歳です渡した値は、位置によって引数に割り当てられます。1つ目の値は name に、2つ目は age に入ります。describe(10, "Ferris") のように順番を間違えて渡すと、型が合わないのでコンパイルエラーになります。
関数は、呼び出した側に値を返せます。戻り値の型は、矢印 -> の後ろに書きます。
fn add(a: i32, b: i32) -> i32 { a + b}
fn main() { let sum = add(3, 4); println!("3 + 4 = {sum}");}実行結果:
3 + 4 = 7セミコロンのルール(大事!)
Section titled “セミコロンのルール(大事!)”上の例の a + b にはセミコロンがないことに気づきましたか? これはRustの大切な考え方です。
- セミコロンなしの式は、そのまま返される値になります。
- セミコロンを付けると文(statement)になり、何も返さなくなります。
なので、次のコードは動きません。
fn add(a: i32, b: i32) -> i32 { a + b; // ❌ セミコロンがあると「何も返さない」ことになる。でも i32 を返すと約束している}コンパイラは「この関数は i32 を返すはずなのに返していない」とエラーを出します。最後の行のセミコロンを消せば直ります。
まとめて使ってみる
Section titled “まとめて使ってみる”fn square(n: i32) -> i32 { n * n}
fn main() { let result = square(5); println!("5の2乗は{result}です");}実行結果:
5の2乗は25です1. 摂氏を華氏に変換する
Section titled “1. 摂氏を華氏に変換する”摂氏の温度を f64 で受け取り、華氏に変換して返す関数 to_fahrenheit を書いてください。式は c * 9.0 / 5.0 + 32.0 です。0度、100度、37度で呼び出してみましょう。ヒント:シグネチャは fn to_fahrenheit(c: f64) -> f64 で、本体はセミコロンのない式1つだけです。
解答を見る
fn to_fahrenheit(c: f64) -> f64 { c * 9.0 / 5.0 + 32.0}
fn main() { println!("0°Cは{}°Fです", to_fahrenheit(0.0)); println!("100°Cは{}°Fです", to_fahrenheit(100.0)); println!("37°Cは{}°Fです", to_fahrenheit(37.0));}実行結果:
0°Cは32°Fです100°Cは212°Fです37°Cは98.6°Fです0 ではなく 0.0 を渡していることに注目してください。引数は f64 で、Rustは整数を勝手に浮動小数点数に変えてはくれません。f64 に小数部分がないとき、{} は .0 を付けずに表示します。だから 32.0 ではなく 32 と表示されるのです。
2. 3つの中でいちばん大きい数
Section titled “2. 3つの中でいちばん大きい数”3つの数のうちいちばん大きいものを返す関数 largest(a: i32, b: i32, c: i32) -> i32 を書いてください。(3, 9, 4) と (-2, -8, -5) で試しましょう。ヒント:Rustでは if は式です(if / elseを参照)。なので、if / else if / else のチェーンを関数の最後の行にできます。
解答を見る
fn largest(a: i32, b: i32, c: i32) -> i32 { if a >= b && a >= c { a } else if b >= c { b } else { c }}
fn main() { println!("{}", largest(3, 9, 4)); println!("{}", largest(-2, -8, -5));}実行結果:
9-2どの分岐もセミコロンで終わっていません。それぞれが式になっていて、if のチェーン全体がそのうちの1つを返し、それが戻り値になります。> ではなく >= を使っているので、同じ値が並んだときもちゃんと値を返せます。
- 関数は
fnで定義し、名前()で呼び出します。 - 引数は関数への入力で、それぞれに型が必要です(
fn greet(name: &str))。 - 戻り値の型は
-> 型で宣言します。 - セミコロンのない最後の式が戻り値になります。
return 値;も使えますが、ふつうは途中で早めに返したいときに使います。
理解度チェック
Section titled “理解度チェック”理解度チェック
1. Rustでは、関数の引数それぞれに型を書く必要がありますか?
2. 関数の戻り値の型はどう宣言しますか?
3. 関数の最後にある a + b(セミコロンなし)が戻り値になるのはなぜですか?
4. 関数を呼び出し位置の上に定義するか下に定義するか(たとえば main の上か下か)は関係ありますか?
スコア: 0 / 4
さらに詳しく
Section titled “さらに詳しく”- 関数 — The Rust Programming Language 日本語版:引数、戻り値、文と式の違いを解説した公式の章です。
- 文と式 — The Rust Programming Language 日本語版:セミコロンのルールの背景にある考え方を、もう少し詳しく見ていきます。
- 関数 — Rust By Example 日本語版:早めの
returnや、何も返さない関数も含む、実行できるサンプルです。 - Functions — The Rust Reference(英語):関数の定義についての正確なルールです。細かいところまで知りたくなったときにどうぞ。
- The
fnkeyword — 標準ライブラリのドキュメント(英語):関数の書き方を例付きで短くまとめています。