Rustの関数を徹底解説!定義、引数、戻り値、文と式…

Rustの関数を徹底解説!定義、引数、戻り値、文と式…

Rustの関数を徹底解説!定義、引数、戻り値、文と式…

こんにちは!今日もRustの学習記録です。
引き続き、The Rust Programming Language 日本語版 (通称 “The Book”) を読み進めていきます。

今回は、The Bookの「関数」の章を学びます。
(3.3. 関数 – The Rust Programming Language 日本語版)

Rustの関数:基本の形

Rustのプログラムにおいて、main 関数は特別な関数であり、多くのプログラムでエントリーポイント(最初に実行される関数)となります。


fn main() {
    // メイン関数ブロック
    sub_function(); // 関数の呼び出し
}

fn sub_function() {
    // サブ関数ブロック
    println!("sub_function関数が呼び出されました");
}

新しい関数を宣言するには、fn キーワードを使用します。
Rustでは、関数名と変数名にはスネークケース (snake_case) を使うのが慣例です。
スネークケースとは、全て小文字で、単語の区切りにアンダースコア (_) を使う書き方です。

関数の定義は、

  1. fn キーワード
  2. 関数名
  3. ()
  4. { 関数本体 }

という形になります。

Rustのコンパイラは、関数がどこで定義されているか (呼び出し元より前か後か) は気にしません。


fn sub_function() {
    println!("sub_functionの呼び出し、前配置");
}

fn main() {
    sub_function();
    next_function();
}

fn next_function() {
    println!("next_functionの呼び出し、後配置");
}

出力結果:

sub_functionの呼び出し、前配置
next_functionの呼び出し、後配置

もちろん、関数の中で別の関数を呼び出すことも可能です。


fn sub_function() {
    println!("sub_functionの呼び出し、前配置");
}

fn main() {
    next_function();
}

fn next_function() {
    println!("next_functionの呼び出し、後配置");
    sub_function(); // 関数の中で関数の呼び出し
}

出力結果:

next_functionの呼び出し、後配置
sub_functionの呼び出し、前配置

関数の引数

関数は、引数 (ひきすう) を持つように定義できます。
引数には、

  • 仮引数 (parameter): 関数定義側の引数
  • 実引数 (argument): 関数呼び出し側の引数

の2種類がありますが、日本語では特に区別せず、どちらも「引数」と呼ぶことが多いです。


fn sub_function(x: i32) { // x が仮引数
    println!("数字は{}", x);
}

fn main() {
    sub_function(10); // 10 が実引数
}

出力結果:

数字は10

Rustでは、関数の仮引数の型は必ず宣言しなければなりません。これは、Rustの安全性と明確性を高めるための設計上の決定です。

複数の引数を持つ場合は、カンマ (,) で区切ります。


fn sub_function(x: i32, y: char) {
    println!("数字の{}と文字の{}", x, y);
}

fn main() {
    sub_function(10, 't');
}

出力結果:

数字の10と文字のt

文 (statement) と式 (expression)

Rustの関数本体は、文 (statement)式 (expression) から構成されます。
この違いを理解することは、Rustのコードを読み書きする上で非常に重要です。

…とは言え、最初はちょっとややこしいので、AI (Gemini) に解説してもらいました。

AI:

  • 文 (Statement):

    • 何らかの処理を行う命令であり、値を返しません。
    • 主に、変数の宣言や代入、制御構造 (if, for など) が該当します。
    • Rustでは、文の末尾にはセミコロン (;) をつけるのが一般的です。
  • 式 (Expression):

    • 評価されると何らかの値を返します。
    • 算術演算、関数呼び出し、ブロック ({}) などが該当します。
    • 式の末尾にはセミコロン (;) をつけません。

具体例を見てみましょう。


fn main() {
    let y = 6; // 文 (変数宣言)

    let x = {
        let x = 3;
        x + 1 // 式 (ブロックの最後の式)
    };

    println!("The value of x is: {}", x); // 4
    println!("The value of y is: {}", y); // 6
}
  • let y = 6; は文です。変数 y に値 6 を代入する命令であり、値を返しません。
  • { let x = 3; x + 1 } はブロックであり、式です。ブロック内の最後の式 x + 1 の結果である 4 が、ブロック全体の評価結果となります。
  • let x = (let y = 6); はエラーになります。let y = 6 は文であり、値を返さないためです。

Rustは式指向言語であり、多くの構文が式として扱われます。
この特徴により、Rustでは簡潔で表現力豊かなコードを記述できます。

セミコロン (;) の有無に注意:
式の末尾にセミコロンを付けると、文に変わります。文は値を返さないため、注意が必要です。

関数の戻り値

関数の戻り値とは、関数が処理を行った結果として呼び出し元に返す値のことです。

Rustでは、

  • 関数の戻り値の型は、関数シグニチャ (関数定義の最初の行) の中で、矢印 (->) の後に宣言します。
  • 関数内で return キーワードを使って値を返すことができます。
  • return を省略した場合、関数本体の最後の式の評価結果が自動的に戻り値となります。

fn add(x: i32, y: i32) -> i32 {
    let a = 3;
    let b = 4;
    let s = a + b;
    x + y // 最後の式が戻り値
}

fn main() {
    let result = add(5, 3);
    println!("5 + 3 = {}", result); // 出力: 5 + 3 = 8
}

add 関数の中で変数 a, b, s についての計算を行っていますが、
結果として返される値は、最後の式 x + y の評価結果です。

関数内で複数の値を返すような式はコンパイルエラーになります。

コンパイラは最初に見つかった式の型を戻り値と推測するため、returnキーワードが使用されていない場合は、関数の戻り値は最後に評価される「式」の結果となります。

return 文は、関数のどこに書かれていても有効です。
return 文が実行されると、その時点で関数は終了し、値を返します。

関数の戻り値の型宣言と、returnで返される値の型が一致しない場合はエラーとなります。

注意
関数内で複数の値を返す式があるとコンパイルエラーになります。
関数内でreturn文を使わなかった場合、最後の式の評価結果が戻り値となります。途中の処理は戻り値に影響しません。

今回の学習を終えて

今回は、The Bookの「関数」の章を読み、Rustの関数の基本について学びました。

特に、

  • 関数の定義方法 (fn キーワード、スネークケース)
  • 引数の扱い (仮引数と実引数、型宣言)
  • 文と式の違い
  • 戻り値の扱い (-> での型宣言、最後の式、return)

は、Rustプログラミングの基礎となる重要な概念です。

次回は、制御フロー (if, for, while) について学習する予定です。
それが終わったら、簡単なプログラムを作りながら、今回学んだ関数や、以前に学んだデータ型などを復習していこうと思います。

//を使うとその行をコメントアウトすることができる。ということもわかりました。

Rustはエラー時にコメントがわかりやすくてとても良いですね。
英語ではあるけど、
mismatched typesとか
consider removing this semicolonとか
英語苦手だけどなんとなく言ってる意味がわかるのでエラーが出た時はしっかりとエラー文を読むことで解決に繋がりそう。

Comments

No comments yet. Why don’t you start the discussion?

    コメントを残す

    メールアドレスが公開されることはありません。 が付いている欄は必須項目です