コンテンツにスキップ

Rust入門

Rustはシステムプログラミング言語です。CやC++と同じような用途、たとえばOS、ゲームエンジン、ブラウザ、データベース、そして速さと細かい制御が大切なコマンドラインツールなどに使われます。

Rustが特別なのは、そうした低レベルな性能を、昔ながらの「うっかりミスの落とし穴」なしに手に入れられることです。C言語では、解放済みのメモリをうっかり読んでしまったり、データ競合を起こしたりするのは簡単です。Rustでは、そういうコードはたいていコンパイルすら通りません。ビルドの段階でコンパイラが止めてくれるのです。

Rustは Graydon Hoare の個人プロジェクトとして始まり、のちに彼がMozillaに持ち込んで支援を受けるようになりました。2015年に安定版の1.0がリリースされ、現在は Rust Foundation(英語)と大きなオープンソースコミュニティによって開発が続けられています。

これまでは、次の2つのどちらかを選ぶしかありませんでした。

  • 低レベル言語(C、C++):高速でハードウェアに近いけれど、メモリは自分で手作業で管理します。ミスをするとクラッシュやセキュリティホールにつながります。
  • 高レベル言語(Python、Java、Go):安全で書きやすいけれど、ガベージコレクタ(garbage collector)に頼っているため、性能や動作の予測しやすさが犠牲になります。

Rustの大きなアイデアは、3つ目の選択肢です。所有権(ownership)と呼ばれるしくみ(このコースの後半で学びます)を使って、メモリ安全性をコンパイル時に保証します。ガベージコレクタもなく、手動の free() もいりません。メモリがいつ不要になるかは、コンパイラが判断してくれます。

あなたが知っているかもしれない言語と比べて、Rustがどのあたりに位置するかをざっくりまとめました。

言語 速さ メモリ安全性 ガベージコレクタ
C / C++ 速い 手動管理で、ミスしやすい なし
Go まずまず 安全 あり
Python 遅め 安全 あり
Rust 速い 安全(コンパイル時にチェック) なし

ポイントは、Rustが「C並みの速さ」と「高レベル言語並みの安全性」を同時に目指しているということです。実際のコードを使ったくわしい比較は、Rust vs C++・Go・Pythonを見てください。

あなたも知らないうちに、すでにRustで書かれたものを使っているかもしれません。

  • Firefox — レンダリングエンジンの一部がRustで書かれています
  • Cloudflare と Discord — 性能が重要なバックエンドサービスで使われています
  • Linuxカーネル — 今ではRustで書かれたドライバを受け入れています
  • CLIツール — ripgrep、bat、fd など、速くて人気のツールがあります
  • WebAssembly — ブラウザでネイティブ並みの速さのコードを動かすなら、Rustは有力な選択肢です

細かいところはまだわからなくて大丈夫です。どれだけ読みやすいかだけ見てみてください。

fn main() {
let name = "Rustacean";
println!("こんにちは、{name}さん!");
}

実行結果:

こんにちは、Rustaceanさん!
▶ 実際に試してみよう

「安全」とは実際にどういうことか

Section titled “「安全」とは実際にどういうことか”

「メモリ安全性」と言われてもピンとこないかもしれないので、具体的な例を見てみましょう。3つの点数が入ったリストがあって、存在しない10番目の点数を取り出そうとしたとします。

C言語では、これが許されてしまいます。プログラムは、リストのあとのメモリにたまたま入っている何かを黙って読み込みます。でたらめな数値が返ってくるかもしれないし、クラッシュするかもしれないし、セキュリティホールになるかもしれません。しかも、何の警告もありません。

Rustはこれを見逃しません。コンパイラがミスに気づける場合は、プログラムのビルドそのものを拒否します。

fn main() {
let scores = [90, 85, 77];
println!("{}", scores[9]);
}
error: this operation will panic at runtime
--> src/main.rs:3:20
|
3 | println!("{}", scores[9]);
| ^^^^^^^^^ index out of bounds: the length is 3 but the index is 9

エラーメッセージは「この操作は実行時にパニックします。インデックスが範囲外です。長さは3なのにインデックスは9です」という意味です。

そして、要素があるかどうかわからないときのために、Rustには丁寧なたずね方が用意されています。.get() は、でたらめな値を返す代わりに「はい、どうぞ」か「何もありません」(None)のどちらかで答えてくれます。

fn main() {
let scores = [90, 85, 77];
println!("最初の点数: {}", scores[0]);
println!("10番目の点数: {:?}", scores.get(9));
}

実行結果:

最初の点数: 90
10番目の点数: None
▶ 実際に試してみよう

[...]、.get()、None についてはまだ気にしなくて大丈夫です。配列とOptionでちゃんと学びます。今のポイントは、「読んではいけないメモリを読む」タイプのバグは、プログラムの実行前に見つかるか、実行中に安全に処理されるか、どちらかになるということです。

正直に言うと、最初の1〜2週間はもどかしく感じるかもしれません。所有権や借用(borrowing)は本当に新しい考え方ですし、「動くはず」と思ったコードをコンパイラに拒否されることもあります。でも、そのつまずきは、コンパイラがより安全なコードの書き方を教えてくれている証拠です。そして、多くの人が思うより早く理解できるようになります。

このコースは、その学習曲線をなだらかにするように作られています。小さなステップ、実際に動く例、そしてすべての例に付いた 実際に試してみよう ボタンで進めていきます。

「ちょっと味見」のプログラムを書き換えて、あなたの名前であいさつするようにし、2行目に Rustへようこそ! と表示してください。ヒント:println! 1つで1行が出力されるので、2つ必要です。

解答を見る
fn main() {
let name = "Sam";
println!("こんにちは、{name}さん!");
println!("Rustへようこそ!");
}

実行結果:

こんにちは、Samさん!
Rustへようこそ!
▶ 実際に試してみよう

Rust という単語と 2015 という年を2つの名前に保存し、その両方を使って Rust 1.0は2015年にリリースされました。 という文を表示してください。ヒント:1つの println! の中に {name} を2つ以上入れられます。

解答を見る
fn main() {
let language = "Rust";
let year = 2015;
println!("{language} 1.0は{year}年にリリースされました。");
}

実行結果:

Rust 1.0は2015年にリリースされました。
▶ 実際に試してみよう
  • Rustは速くて安全なシステム言語です。C並みの速さで、ガベージコレクタはありません。
  • 所有権のしくみによって、メモリのバグをコンパイル時に防ぎます。
  • ブラウザ、OSカーネル、クラウドサービス、CLIツール、WebAssemblyなどで使われています。
  • 学習曲線は確かにありますが、短いものです。コンパイラはあなたの味方です。

次は、Rustをインストールして、自分のパソコンで最初のプログラムを動かしてみましょう。

理解度チェック

1. Rustはガベージコレクタなしで、どうやってメモリ安全性を実現していますか?

2. 比較表によると、RustとGoに共通しているのはどれですか?

3. Rustの開発者は自分たちのことを何と呼んでいますか?

スコア: 0 / 3

  • The Rust Programming Language 日本語版「はじめに」:公式の本がどんな人向けで、どう構成されているかを説明しています。このコースのおともとして、無料で読める最高の本です。
  • Rustの公式サイト:「なぜRustか?」(パフォーマンス、信頼性、生産性)の紹介や、Rustを使っている企業の事例が載っています。
  • Rustを学ぶ:Rust by Example や Rustlings の練習問題など、公式の学習リソースの一覧です。
  • Announcing Rust 1.0 — Rust Blog(英語):Rustが安定版になったことを告げた2015年の記事です。「安定性」があなたのコードに何を約束するのかも書かれています。
  • Rust Foundation(英語):Rustプロジェクトとそのメンテナーを支える非営利団体です。