Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

関数

処理をまとめて再利用可能にする「関数」について学びます。

関数とは

関数は「処理をまとめた部品」です。

fn main() {
    greet();  // 関数を呼び出す
}

fn greet() {
    println!("こんにちは!");
}

なぜ関数を使うのか

  1. 再利用: 同じ処理を何度も書かなくて済む
  2. 整理: コードを意味のある単位に分割
  3. テスト: 部品ごとにテストしやすい

関数の定義

#![allow(unused)]
fn main() {
fn 関数名() {
    // 処理
}
}
  • fn: 関数を定義するキーワード
  • 関数名: snake_case で命名
  • (): 引数リスト
  • {}: 関数の本体

命名規則

#![allow(unused)]
fn main() {
fn calculate_total() { }   // OK: snake_case
fn calculateTotal() { }    // 動くが警告が出る
}

Rustでは関数名に snake_case(小文字とアンダースコア)を使います。

引数

関数にデータを渡せます。

fn main() {
    greet("太郎");
    greet("花子");
}

fn greet(name: &str) {
    println!("こんにちは、{}さん!", name);
}

出力:

こんにちは、太郎さん!
こんにちは、花子さん!

引数の書き方

#![allow(unused)]
fn main() {
fn 関数名(引数名: 型) {
    // 処理
}
}

型注釈は必須です。省略できません。

複数の引数

fn main() {
    print_sum(5, 3);
}

fn print_sum(a: i32, b: i32) {
    println!("{} + {} = {}", a, b, a + b);
}

戻り値

関数は値を返すことができます。

fn main() {
    let result = add(5, 3);
    println!("結果: {}", result);
}

fn add(a: i32, b: i32) -> i32 {
    a + b  // セミコロンなし = この値を返す
}

戻り値の書き方

#![allow(unused)]
fn main() {
fn 関数名(引数) -> 戻り値の型 {
    戻り値  // セミコロンなし
}
}
  • ->: 戻り値の型を示す
  • 最後の式の値が返される(セミコロンをつけない)

return を使う方法

#![allow(unused)]
fn main() {
fn add(a: i32, b: i32) -> i32 {
    return a + b;  // 明示的にreturn
}
}

return を使うと、関数の途中でも値を返して終了できます:

#![allow(unused)]
fn main() {
fn absolute(n: i32) -> i32 {
    if n < 0 {
        return -n;  // ここで終了
    }
    n  // nが0以上の場合
}
}

式と文

Rustではセミコロンの有無が重要です。

fn main() {
    let x = {
        let y = 3;
        y + 1  // セミコロンなし → これが式の値になる
    };
    println!("{}", x);  // 4
}
fn main() {
    let x = {
        let y = 3;
        y + 1;  // セミコロンあり → 値を返さない(()を返す)
    };
    // xは () 型になる
}
式(Expression)文(Statement)
セミコロンなしあり
値を返すはいいいえ
5 + 3, x * 2let x = 5;, x = 3;

関数を使った例

例1: 面積の計算

fn main() {
    let width = 10;
    let height = 5;
    let area = calculate_area(width, height);
    println!("面積: {}", area);
}

fn calculate_area(width: i32, height: i32) -> i32 {
    width * height
}

例2: 偶数判定

fn main() {
    for i in 1..=10 {
        if is_even(i) {
            println!("{}は偶数", i);
        }
    }
}

fn is_even(n: i32) -> bool {
    n % 2 == 0
}

例3: 最大値を求める

fn main() {
    let max = maximum(10, 25);
    println!("最大値: {}", max);
}

fn maximum(a: i32, b: i32) -> i32 {
    if a > b {
        a
    } else {
        b
    }
}

関数の設計指針

1. 一つのことをうまくやる

#![allow(unused)]
fn main() {
// 良い例:一つのことに集中
fn calculate_tax(price: i32) -> i32 {
    price / 10
}

fn calculate_total(price: i32, tax: i32) -> i32 {
    price + tax
}

// 悪い例:複数のことをやっている
fn calculate_and_print_total(price: i32) {
    let tax = price / 10;
    let total = price + tax;
    println!("税込: {}", total);
}
}

2. 適切な名前をつける

#![allow(unused)]
fn main() {
// 良い例:何をするかわかる
fn calculate_area(width: i32, height: i32) -> i32 { ... }
fn is_valid_email(email: &str) -> bool { ... }

// 悪い例:わかりにくい
fn calc(a: i32, b: i32) -> i32 { ... }
fn check(s: &str) -> bool { ... }
}

3. 引数は少なめに

引数が多すぎると使いにくくなります。3〜4個を超えたら構造体の使用を検討。

まとめ

要素説明
fn関数を定義
引数関数に渡すデータ。型注釈必須
->戻り値の型を示す
戻り値最後の式(セミコロンなし)が返る
return明示的に値を返す

確認テスト

Q1. 関数の戻り値について正しいのは?

Q2. 関数の引数について正しいのは?

Q3. double(triple(2)) の結果は?(double: n*2, triple: n*3)

Q4. fn add(a: i32, b: i32) -> i32 { a + b; } のエラーを修正するには?

Q5. FizzBuzz問題で「15」は何と出力される?


次のドキュメント: 05_collections_basic.md