コンテンツにスキップ

プログラミング/Rust

出典: フリー教科書『ウィキブックス(Wikibooks)』

Rustの誕生と哲学

[編集]

Rustは、Mozilla Research によって2010年に開始されたプログラミング言語で、システムプログラミングの革新を目指して生まれました。高性能かつメモリ安全性を追求する言語として、従来のC言語やC++が抱える多くの問題を解決することを目的としています。

基本的な文法と特徴

[編集]

変数と型システム

[編集]

Rustは静的型付け言語で、型推論により冗長な型宣言を避けることができます。

// 不変変数(デフォルト)
let x = 5;
// x = 6; // コンパイルエラー

// 可変変数
let mut y = 10;
y += 5; // 可能

// 明示的な型指定
let z: f64 = 3.14159;

// タプル
let coordinates: (i32, i32) = (10, 20);
let (x_coord, y_coord) = coordinates;

// 構造体
struct Point {
    x: i32,
    y: i32,
}

let origin = Point { x: 0, y: 0 };

パターンマッチング

[編集]

Rustの強力な制御構造の一つ、パターンマッチングは型安全性と表現力を提供します。

enum Fruit {
    Apple(String),
    Banana { weight: f32 },
    Cherry,
}

fn describe_fruit(fruit: Fruit) {
    match fruit {
        Fruit::Apple(variety) => {
            println!("りんご(品種: {})", variety);
        },
        Fruit::Banana { weight } if weight > 100.0 => {
            println!("大きなバナナ({}g)", weight);
        },
        Fruit::Banana { weight } => {
            println!("通常サイズのバナナ({}g)", weight);
        },
        Fruit::Cherry => {
            println!("さくらんぼ");
        }
    }
}

所有権とライフタイム

[編集]

Rustの最も革新的な特徴は、メモリ安全性を保証する所有権システムです。

fn main() {
    // 文字列の所有権
    let s1 = String::from("こんにちは");
    let s2 = s1; // 所有権の移動
    // println!("{}", s1); // コンパイルエラー

    // 参照と借用
    let s3 = String::from("世界");
    let len = calculate_length(&s3);
    println!("文字列 '{}' の長さは {} です", s3, len);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

// ライフタイムの明示
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

並行処理

[編集]

Rustは安全な並行処理を言語レベルで提供します。

use std::thread;
use std::sync::{Arc, Mutex};

fn main() {
    // スレッド生成
    let handle = thread::spawn(|| {
        for i in 1..10 {
            println!("スレッド内のカウント: {}", i);
            thread::sleep(std::time::Duration::from_millis(100));
        }
    });

    // スレッド間で安全に共有される可変状態
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let counter_clone = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter_clone.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("最終的なカウンター値: {}", *counter.lock().unwrap());
}

エラーハンドリング

[編集]

Rustは、実行時エラーではなくコンパイル時にエラーを検出することを重視しています。

use std::fs::File;
use std::io::{self, Read};

fn read_username_from_file() -> Result<String, io::Error> {
    let mut username = String::new();
    
    // エラー伝播演算子 ?
    File::open("username.txt")?.read_to_string(&mut username)?;
    
    Ok(username)
}

fn main() {
    match read_username_from_file() {
        Ok(username) => println!("ユーザー名: {}", username),
        Err(e) => println!("エラーが発生しました: {}", e),
    }
}

クレート(パッケージ)システム

[編集]

Rustのパッケージ管理システムCargoは、依存関係管理とビルドプロセスを簡素化します。

# Cargo.toml
[package]
name = "my_project"
version = "0.1.0"

[dependencies]
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.0", features = ["full"] }

Rustの適用領域

[編集]

Rustは以下のような分野で特に強みを発揮します:

  • システムプログラミング
  • ネットワークサービス
  • ゲームエンジン
  • クロスプラットフォームアプリケーション
  • セキュリティ重視のソフトウェア開発

まとめ

[編集]

Rustは、メモリ安全性、並行性、パフォーマンスを兼ね備えた現代的なプログラミング言語です。従来の低レベル言語の課題を解決し、高い生産性と信頼性を提供します。学習曲線は急峻ですが、習得すれば非常に強力な開発能力を手に入れることができるでしょう。