はじめに
Rustは、システムプログラミング言語として高いパフォーマンスとメモリ安全性を提供します。このブログ記事では、初心者向けにRustの基本から始めて、実際のWebアプリケーションの構築までをカバーします。
20章にわたる詳細な説明とコード例を通じて、Rustの魅力を体験しましょう。特にWindows、Linux、macOSユーザー向けに、環境設定の手順も詳しく説明します。
第1章: Rustのインストールと環境設定
Windowsでのインストール
-
Rustのインストーラーをダウンロード:
- Rustの公式サイトから「rustup-init.exe」をダウンロードします。
-
インストーラーを実行:
- ダウンロードした「rustup-init.exe」をダブルクリックして実行します。
- インストールオプションが表示されたら、デフォルト設定を選択します。
- Visual Studio C++ Build Toolsのインストールを求められた場合は、指示に従ってインストールします。
-
環境変数の設定:
- インストールが完了すると、コマンドプロンプトを開いて以下のコマンドを実行し、インストールが成功したか確認します。
rustc --version
-
Visual Studio Codeのインストール:
- 推奨されるエディタはVisual Studio Codeです。拡張機能「rust-analyzer」をインストールして、Rustの開発をサポートします。
Linux/macOSでのインストール
-
ターミナルを開く:
- ターミナルを開き、以下のコマンドを実行します。
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
-
インストールオプションの選択:
- インストールスクリプトを実行すると、オプションが表示されます。デフォルトの「1」を選んで進めます。
-
環境変数の設定:
- インストール後、以下のコマンドを実行して環境変数を設定します。
source $HOME/.cargo/env
-
バージョン確認:
- 以下のコマンドでRustのインストールが成功したか確認します。
rustc -V cargo -V
第2章: Hello Worldプログラム
Rustでのプログラミングは、main
関数から始まります。以下のコードを使って、最初のプログラムを作成しましょう。
fn main() {
println!("Hello, world!");
}
このプログラムをコンパイルして実行することで、Rustの基本的な動作を確認できます。ターミナルで以下のコマンドを実行します。
cargo run
第3章: 変数とデータ型
Rustの変数は、デフォルトで不変です。可変にするにはmut
キーワードを使います。Rustの主なデータ型には、整数、浮動小数点、ブール、文字列などがあります。
let x = 5;
let mut y = 10;
y += 5;
第4章: 所有権と借用
Rustのユニークな特徴の一つが所有権システムです。これにより、メモリ管理が効率的に行われます。以下は所有権の基本的な例です。
fn main() {
let s1 = String::from("hello");
let s2 = s1; // s1の所有権がs2に移動
// println!("{}", s1); // これはエラーになります
}
第5章: 構造体と列挙型
Rustでは、構造体と列挙型を使って複雑なデータ型を定義できます。
struct Point {
x: i32,
y: i32,
}
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
}
第6章: 関数とメソッド
Rustの関数は、fn
キーワードを使って定義します。メソッドは構造体に関連付けられた関数です。
fn add(x: i32, y: i32) -> i32 {
x + y
}
impl Point {
fn area(&self) -> i32 {
self.x * self.y
}
}
第7章: エラーハンドリング
Rustでは、Result
型を使ってエラーを扱います。
fn divide(x: i32, y: i32) -> Result<i32, String> {
if y == 0 {
Err(String::from("Cannot divide by zero"))
} else {
Ok(x / y)
}
}
第8章: コレクション型
Rustには、ベクタ、文字列、ハッシュマップなどのコレクション型があります。これらはデータを格納し、操作するための便利な方法を提供します。
let mut numbers = vec![1, 2, 3, 4, 5];
numbers.push(6);
println!("{:?}", numbers);
第9章: イテレータ
イテレータは、コレクションを順番に処理するための強力なツールです。for
ループと組み合わせて使うことができます。
let numbers = vec![1, 2, 3, 4, 5];
for num in numbers.iter() {
println!("{}", num);
}
第10章: クロージャ
クロージャは、関数のように振る舞う匿名関数です。環境をキャプチャすることができます。
let add_one = |x: i32| x + 1;
println!("{}", add_one(5));
第11章: スマートポインタ
スマートポインタは、追加のメタデータや機能を持つポインタです。Box<T>
, Rc<T>
, RefCell<T>
などがあります。
let b = Box::new(5);
println!("{}", b);
第12章: モジュールとパッケージ
モジュールは、コードを整理するための方法です。mod
キーワードを使って定義します。
mod my_module {
pub fn say_hello() {
println!("Hello from my module!");
}
}
fn main() {
my_module::say_hello();
}
第13章: テスト
Rustには、組み込みのテストフレームワークがあり、コードの動作を確認するためのテストを書くことができます。
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
第14章: 並行性
Rustは、スレッドとチャネルを使って並行プログラミングをサポートします。std::thread
を使ってスレッドを作成できます。
use std::thread;
fn main() {
let handle = thread::spawn(|| {
for i in 1..10 {
println!("hi number {} from the spawned thread!", i);
}
});
handle.join().unwrap();
}
第15章: ファイル入出力
Rustでは、std::fs
を使ってファイルの読み書きを行います。
use std::fs::File;
use std::io::prelude::*;
fn main() -> std::io::Result<()> {
let mut file = File::create("output.txt")?;
file.write_all(b"Hello, world!")?;
Ok(())
}
第16章: ジェネリクスとトレイト
ジェネリクスは、型に依存しないコードを書くための方法です。トレイトは、共通の振る舞いを定義します。
fn largest<T: PartialOrd>(list: &[T]) -> &T {
let mut largest = &list[0];
for item in list.iter() {
if item > largest {
largest = item;
}
}
largest
}
第17章: エラーハンドリングの強化
Rustでは、Result
とOption
を使ってエラーを扱います。?
演算子を使ってエラー処理を簡素化できます。
fn read_file(filename: &str) -> Result<String, std::io::Error> {
let mut file = File::open(filename)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Ok(contents)
}
第18章: Webアプリケーションの構築
ここからは、Rustを使ったWebアプリケーションの構築に入ります。actix-web
フレームワークを使用して、基本的なWebサーバを作成します。
必要なフレームワークのインストール
まず、actix-web
をプロジェクトに追加します。Cargo.tomlファイルに以下を追加します。
[dependencies]
actix-web = "4"
次に、以下のコマンドを実行して依存関係をインストールします。
cargo build
基本的なWebサーバの作成
以下のコードを使用して、シンプルなWebサーバを作成します。
use actix_web::{web, App, HttpServer, Responder};
async fn greet() -> impl Responder {
"Hello, Rust!"
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/", web::get().to(greet))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
このコードは、127.0.0.1:8080
で動作するシンプルなHTTPサーバを立ち上げ、/
エンドポイントにアクセスすると「Hello, Rust!」と返します。
第19章: REST APIの実装
REST APIを実装するために、actix-web
を使ってエンドポイントを追加します。
use actix_web::{web, App, HttpServer, Responder, HttpResponse};
async fn get_items() -> impl Responder {
HttpResponse::Ok().json(vec!["Item1", "Item2"])
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/items", web::get().to(get_items))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
第20章: データベースとの連携
最後に、Rustでデータベースと連携する方法を学びます。diesel
を使って、データベース操作を行います。
use diesel::prelude::*;
use diesel::sqlite::SqliteConnection;
fn establish_connection() -> SqliteConnection {
SqliteConnection::establish("test.db")
.expect(&format!("Error connecting to {}", "test.db"))
}
このチュートリアルを通じて、Rustの基本から実際のアプリケーション構築までを学ぶことができました。Rustの強力な機能を活用して、さらに多くのプロジェクトに挑戦してみてください。