Rustは、パフォーマンス、型安全性、並行処理、メモリ安全性を重視した汎用プログラミング言語です。
Rust は複数のプログラミング パラダイムをサポートしています。不変性、高階関数、代数的データ型、パターン マッチングなど、関数型プログラミングの考え方の影響を受けています。また、構造体、列挙型、トレイト、メソッドを介したオブジェクト指向プログラミングもサポートしています。Rust は、従来のガベージ コレクタを使用せずにメモリ安全性(つまり、すべての参照が有効なメモリを指していること)を強制します。代わりに、コンパイル時に参照のオブジェクトのライフタイムを追跡する「借用チェッカー」によって、メモリ安全性のエラーやデータ競合が防止されます。
ソフトウェア開発者のグレイドン・ホアは、 Mozillaに勤務していた2006年にRustを開発し、Mozillaは2009年に正式にこのプロジェクトを支援しました。最初の安定版であるRust 1.0は2015年5月に公開されました。このプロジェクトは2021年2月からRust Foundationの支援を受けています。
Rustは、特にWebサービスやシステムソフトウェアなど、多くのソフトウェアプロジェクトで採用されています。学術研究も盛んに行われており、開発者コミュニティも拡大しています。
Rust は、2006 年にMozilla の従業員である Graydon Hoareによる個人的なプロジェクトとして始まりました。MIT Technology Reviewによると、彼はアパートのエレベーターのソフトウェアがクラッシュして故障したことに不満を感じてこのプロジェクトを開始し、[ 20 ]「生存のために過剰に設計された」同名の菌類のグループにちなんでこの言語に名前を付けました。 [ 20 ] 2006 年から 2009 年の間、Rust は Mozilla の他の人には公表されず、Hoare の自由時間に書かれていました。[ 21 ] : 7:50 Hoare は、Mozilla の少数のグループがこのプロジェクトに興味を持った後、2009 年頃からこの言語について語り始めました。[ 22 ] Hoare は、1970 年代、1980 年代、1990 年代の言語を影響源として挙げ、CLU、BETA、Mesa、NIL、[注 4 ] Erlang、Newsqueak、Napier、Hermes、Sather、Alef、Limboなどを挙げた。[ 22 ]彼はこの言語を「未来を自らから救うためにやってきた過去の技術」と表現した。[ 21 ] : 8:17 [ 22 ] Rust の初期開発者 Manish Goregaokar も同様に、Rust は「ほとんど数十年前の研究」に基づいていると表現した。[ 20 ]
初期の頃、Rustコンパイラは約38,000行のOCamlで書かれていました。[ 21 ] : 15:34 [ 23 ]初期のRustには、キーワードによる明示的なオブジェクト指向プログラミング[ 21 ] : 10:08や、未初期化から初期化済みへの遷移など、変数の状態変化のための型状態システムなど、現在では存在しないいくつかの機能が含まれていました。[ 21 ] : 13:12obj
Mozilla は 2009 年に Rust プロジェクトを正式に後援しました。[ 20 ]ブレンダン アイヒや他の幹部は、安全なウェブ ブラウザエンジンに Rust を使用する可能性に興味を持ち、パトリック ウォルトン、ニコ マツァキス、フェリックス クロック、マニッシュ ゴレガオカーなどのエンジニアをプロジェクトに配置しました。[ 20 ]プロジェクト開発者が使用した会議室は「オタクの洞窟」と呼ばれ、ドアの外に看板が立てられました。[ 20 ]
この期間中、作業は当初の OCaml コンパイラからLLVM をターゲットとする自己ホスト型コンパイラ(つまりRust で書かれたもの)に移行した。[ 24 ] [注 5 ]所有権システムは 2010 年までに確立された。[ 20 ] Rust のロゴは自転車のチェーンリングを基に 2011 年に開発された。[ 26 ]
Rust 0.1 は、2012 年 1 月 20 日にWindows、Linux、および MacOS 向けに最初の公開リリースとなりました[ 27 ] 。 [ 28 ] 2010 年代初頭には、Mozilla のフルタイムのエンジニアと Mozilla 以外のオープンソースのボランティアの関与が増加しました。[ 20 ]
2012年から2015年にかけては、Rustの型システムに大きな変更が加えられました。[ 21 ] : 18:36 [ 20 ]所有権システムによるメモリ管理が徐々に統合され、拡張されました。2013年までに、ガベージコレクタはほとんど使用されなくなり、所有権システムに置き換えられました。[ 20 ]pure型状態、キーワード、[ 29 ]さまざまな特殊化されたポインタ型、チャネルの構文サポートなど、言語を簡素化するために他の機能も削除されました。[ 21 ] : 22:32
Steve Klabnik氏によると、この時期のRustは、C++(例えば、機能の低レベルなパフォーマンス)、スクリプト言語(例えば、Cargoやパッケージ管理)、関数型プログラミング(例えば、型システム開発)出身の開発者から影響を受けていたという。[ 21 ] : 30:50
グレイドン・ホアは2013年にRustを退任した。[ 20 ]ホアの退任後、Rustは連邦制のガバナンス構造の下で有機的に進化し、当初は6人の「コアチーム」[ 21 ] : 21:45と、その他さまざまなチームに合計30~40人の開発者がいた。[ 21 ] : 22:22新しい言語機能に関するRequest for Comments(RFC)プロセスは2014年3月に追加された。[ 21 ] : 33:47コアチームは2016年までに9人に増え、 1600を超えるRFCが作成された。[ 21 ] : 21:45 [ 21 ] : 34:08
2014年1月のDr. Dobb's JournalのAndrew Binstock氏によると、Rustは「非常に洗練された言語として広く認識されていた」ものの、バージョンごとに大きく変化したため、普及が遅れたという。[ 30 ]この時期のRust開発は、後方互換性を約束できるように、バージョン1.0の機能を最終決定することに重点を置いていた。[ 21 ] : 41:26
Mozillaのスポンサーシップから6年後、Rust 1.0が公開され、 2015年5月15日に最初の安定版リリースとなった。 [ 20 ] 1年後、Rustコンパイラには1,400人以上の貢献者が集まり、Rustパッケージ管理ウェブサイトCrates.ioには5,000以上のサードパーティライブラリが公開された。[ 21 ] : 43:15

Servo ブラウザ エンジンの開発は、Mozilla とSamsungの共同出資により Rust と並行して続けられました。[ 31 ] 2 つのプロジェクトのチームは緊密に連携して作業を進め、Rust の新機能は Servo チームによってテストされ、Servo の新機能は Rust チームへのフィードバックに使用されました。[ 21 ] : 5:41 Servo の最初のバージョンは 2016 年にリリースされました。 [ 20 ] Firefoxウェブ ブラウザは 2016 年 (バージョン 45) の時点で Rust コードを搭載して出荷されましたが、[ 21 ] : 53:30 [ 32 ] Servoのコンポーネントは、 GeckoおよびQuantumプロジェクトの一部として 2017 年 9 月 (バージョン 57) まで Firefox には登場しませんでした。[ 33 ]
Rustツールチェーンのエコシステムは、1.0以降数年間で改善され、Rustfmt、統合開発環境の統合[ 21 ] : 44:56、定期的なコンパイラのテストとリリースサイクル[ 21 ] : 46:48などが含まれるようになった。Rustコミュニティは行動規範と議論のためのIRCチャットを獲得した[ 21 ] : 50 :36
Mozilla以外で最初に採用されたことが知られているのは、Samsung、Facebook(現在はMeta Platforms)、Dropbox、およびember.jsの開発元であるTilde, Inc.の個々のプロジェクトである。[ 21 ] : 55:44 [ 20 ] Amazon Web Servicesは2020年にこれに続いた。[ 20 ]エンジニアは、パフォーマンス、ガベージコレクタの欠如、安全性、および言語での作業の快適さを採用理由として挙げた。Amazonの開発者は、ポルトガルの研究者による、RustコードはJavaで書かれた同様のコードと比較してエネルギー消費が少ないという発見を引用した。[ 20 ] [ 34 ]
2020年8月、MozillaはCOVID-19パンデミックによる企業再編の一環として、世界中の従業員1,000人のうち250人を解雇した。[ 35 ] [ 36 ] Servoの開発チームは解散した。この出来事はRustの将来に対する懸念を引き起こした。[ 37 ]翌週、Rustコアチームは解雇の深刻な影響を認め、Rust財団の計画が進行中であることを発表した。財団の最初の目標は、すべての商標とドメイン名の所有権を取得し、それらの費用に対する財政的責任を負うことだった。[ 38 ]
2021年2月8日、Amazon Web Services、Google、Huawei、Microsoft、Mozillaの5社が設立を発表し、Rust Foundationの設立が発表されました。[ 39 ] [ 40 ]この財団は、助成金やサーバー資金の形でRust開発者に財政支援を提供する予定です。[ 20 ] 2021年4月6日に公開されたブログ記事で、GoogleはAndroid Open Source Project内でC/C++の代替としてRustをサポートすることを発表しました。[ 41 ]
2021年11月22日、コミュニティ行動規範の執行を担当していたモデレーションチームは、「コアチームが自分たち以外には誰にも責任を負わないという姿勢に抗議して」辞任を発表した。[ 42 ] 2022年5月、Rustのリーダーシップ評議会のメンバーは、この事件に対する公式声明を発表した。[ 43 ]
Rust Foundation は 2023 年 4 月 6 日に新しい商標ポリシーの草案を公開したが、Rust のユーザーや貢献者から広範な否定的な反応が寄せられた。[ 44 ]商標ポリシーには、Rust のロゴと名前の使用方法に関するルールが含まれていた。[ 44 ]
Rust の構文はCやC++に似ていますが、[ 45 ] [ 46 ]多くの機能はOCamlなどの関数型プログラミング言語の影響を受けています。[ 47 ] Hoare は Rust を、不満を抱えた C++ 開発者を対象としたものだと述べています。[ 22 ]
以下はRust の「Hello, World!」プログラムです。キーワードは関数fnを表し、マクロ( §マクロを参照) はメッセージを標準出力に出力します。[ 48 ] Rust のステートメントはセミコロンで区切られます。println!
fn main () { println! ( "Hello, World!" ); }Rust の変数letはキーワードで定義されます。[ 49 ]foo以下の例では、type という名前の変数に値を代入しi32、その値を出力します。型注釈は省略できます。:i32
fn main () { let foo : i32 = 10 ; println! ( "fooの値は{foo}です" ); }変数は、キーワードが追加されない限り、デフォルトでは変更できませんmut。[ 50 ]次の例では、コメント//の開始を示す を使用しています。[ 51 ]
fn main () { // このコードは「mut」を追加しないとコンパイルされません。let mut foo = 10 ; println! ( "foo の値は {foo} です" ); foo = 20 ; println! ( "foo の値は {foo} です" ); }複数のlet式で同じ名前の複数の変数を定義できます。これは変数シャドウイングと呼ばれます。変数シャドウイングを使用すると、変数に異なる名前を付けることなく変数を変換できます。[ 52 ]以下の例では、元の値の2倍の同じ名前の新しい変数を宣言しています。
fn main () { let foo = 10 ; // これは "The value of foo is 10" と出力しますprintln! ( "The value of foo is {foo}" ); let foo = foo * 2 ; // これは "The value of foo is 20" と出力しますprintln! ( "The value of foo is {foo}" ); }異なる型の値に対しても変数シャドウイングが可能です。例えば、文字列からその長さを取得する場合などです。
fn main () { let letters = "abc" ; let letters = letters.len ( ) ; }ブロック式は中括弧で囲まれます。ブロック内の最後の式がセミコロンで終わらない場合、ブロックはその末尾の式の値に評価されます。[ 53 ]
fn main () { let x = { println! ( "これはブロック内です" ); 1 + 2 }; println! ( "1 + 2 = {x}" ); }関数本体の末尾の式は戻り値として使用されます: [ 54 ]
fn add_two ( x : i32 ) -> i32 { x + 2 }if表現if条件式は、指定された値が真であるかどうかに基づいてコードを実行しますtrue。は、else値が真と評価される場合に使用できfalse、 は複数の式を組み合わせるために使用できます。[ 55 ]elseif
fn main () { let x = 10 ; if x > 5 { println! ( "値は5より大きい" ); }if x % 7 == 0 { println! ( "値は7で割り切れます" ); } else if x % 5 == 0 { println! ( "値は5で割り切れます" ); } else { println! ( "値は7でも5でも割り切れません" ); } }ifブロックelseは値に評価され、その値を変数に割り当てることができます。[ 55 ]
fn main () { let x = 10 ; let new_x = if x % 2 == 0 { x / 2 } else { 3 * x + 1 }; println! ( "{new_x}" ); }whileループwhile条件が満たされている間、コードブロックを繰り返すために使用できます。[ 56 ]
fn main () { // 4から10までのすべての整数を反復処理するlet mut value = 4 ; while value <= 10 { println! ( "value = {value}" ); value += 1 ; } }forループとイテレータRust のfor ループはコレクションの要素をループします。[ 57 ]式は任意のイテレータfor型で機能します。
fn main () { // 上記と同じ機能を実現するために、範囲構文を使用した`for`を使用します。// 構文4..=10は、4から10までの範囲(10を含む)を意味します。for value in 4 ..= 10 { println! ( "value = {value}" ); } }上記のコードにおいて、はトレイトを実装する型の 値です。中括弧内のコードは、イテレータによって返される各要素に適用されます。4..=10RangeIterator
mapイテレータは、、、filterなどのイテレータに対する関数と組み合わせることができますsum。たとえば、次のコードは、1から100までの3の倍数であるすべての数を合計します。
( 1 ..= 100 ). filter ( | x | x % 3 == 0 ). sum ()loopおよびbreak声明より一般的には、loopキーワードは、が発生するまでコードの一部を繰り返しますbreak。breakは、オプションで値を指定してループを終了することができます。ネストされたループの場合、で示されるラベルを使用して、最も内側のループではなく外側のループを中断できます。[ 58 ]'label_name
fn main () { let value = 456 ; let mut x = 1 ; let y = loop { x *= 10 ; if x > value { break x / 10 ; } }; println! ( "value より小さいか等しい最大の 10 のべき乗: {y}" );let mut up = 1 ; ' outer : loop { let mut down = 120 ; loop { if up > 100 { break 'outer ; }ダウンが4未満の場合、処理を中断します。down /= 2 ; up += 1 ; println! ( "up: {up}, down: {down}" ); } up *= 2 ; } }および式はパターンマッチングに使用できます。たとえば、 は、オプションの整数値が存在する場合はそれmatchを2倍にし、それ以外の場合はゼロを返すために使用できます。[ 59 ]ifletmatch
fn double ( x : Option < u64 > ) -> u64 { match x { Some ( y ) => y * 2 , None => 0 , } }同様に、これは と を使って次のように書くこともできます。ifletelse
fn double ( x : Option < u64 > ) -> u64 { if let Some ( y ) = x { y * 2 } else { 0 } }Rustは強力な型付けと静的型付けを採用しており、コンパイル時にすべての変数の型が既知である必要があります。特定の型の値を異なる型の変数に代入すると、コンパイルエラーが発生します。型が指定されていない場合は、型推論を使用して変数の型を決定します。[ 60 ]
Rust の「ユニット型」と呼ばれる型は()、正確に 1 つの値を持つ具体的な型です。メモリを占有しません (値の不在を表すため)。戻り値の型が指定されていないすべての関数は、暗黙的に を返します()。これは他の C スタイルの言語の に似ていますvoidが、 はvoid型の不在を表し、値を持つことはできません。
デフォルトの整数型はi32、デフォルトの浮動小数点型はです。リテラルf64数値の型が明示的に指定されていない場合は、コンテキストから推論されるか、デフォルトの型が使用されます。[ 61 ]
Rust の整数型は、符号の有無と型が占めるビット数に基づいて命名されます。たとえば、i32は符号付き整数で 32 ビットのストレージを占有しますが、u8は符号なしで 8 ビットのストレージしか占有しません。isizeと は、コンパイル ターゲットのメモリ アドレス バス幅usizeに応じてストレージを占有します。たとえば、32 ビット ターゲット向けにビルドする場合、両方の型は 32 ビットのスペースを占有します。[ 62 ] [ 63 ]
デフォルトでは、整数リテラルは基数 10 ですが、接頭辞を使用して異なる基数がサポートされます。たとえば、2 進数0b11の場合は、8 進数の場合は、16進数の場合は です。デフォルトでは、整数リテラルの型は になります。 などの接尾辞を使用して、リテラルの型を明示的に設定できます。[ 64 ]などのバイトリテラルは、特定の文字のASCII値 ( として)を表すために使用できます。[ 65 ]0o5670xDBi324u32b'X'u8
ブール型はと呼ばれ、または のboolいずれかの値を取ることができます。 は32 ビットのスペースを占有し、Unicode スカラー値を表します。[ 66 ] は、サロゲートではないUnicodeコードポイントです。[ 67 ] IEEE 754浮動小数点数は、単精度浮動小数点数の場合は、倍精度浮動小数点数の場合はでサポートされています。[ 68 ]truefalsecharf32f64
複合型は複数の値を含むことができます。タプルは固定サイズのリストで、型が異なる値を含むことができます。配列は固定サイズのリストで、値はすべて同じ型です。タプル型と配列型の式は、値を列挙することで記述でき、(タプルの場合)または(配列の場合)でアクセスできます。[ 69 ].index[index]
let tuple : ( u32 , bool ) = ( 3 , true ); let array : [ i8 ; 5 ] = [ 1 , 2 , 3 , 4 , 5 ]; let value = tuple.1 ; // true let value = array [ 2 ] ; // 3配列は、単一の値を複数回コピーすることによって構築することもできます。[ 70 ]
let array2 : [ char ; 10 ] = [ ' ' ; 10 ];Rust の所有権システムは、ガベージ コレクタを使用せずにメモリの安全性を保証するルールで構成されています。コンパイル時に、各値はその値の所有者と呼ばれる変数に添付されなければならず、すべての値は正確に 1 つの所有者を持たなければなりません。[ 71 ]値は、代入または関数パラメータとして値を渡すことによって、異なる所有者間で移動されます。値は借用することもできます。つまり、所有者に返される前に、一時的に別の関数に渡されます。[ 72 ]これらのルールにより、Rust はダングリング ポインタの作成と使用を防ぐことができます。[ 72 ] [ 73 ]
fn print_string ( s : String ) { println! ( "{}" , s ); }fn main () { let s = String :: from ( "Hello, World" ); print_string ( s ); // s は print_string によって消費されます// s は移動されたため、これ以上使用できません// 別の print_string(s); を実行するとコンパイルエラーになります}この関数は渡された値のprint_string所有権を取得します。あるいは、参照型 ( )を示すために使用したり、参照 ( ) を作成するために使用したりすることもできます。[ 74 ]String&&String&s
fn print_string ( s : & String ) { println! ( "{}" , s ); }fn main () { let s = String :: from ( "Hello, World" ); print_string ( & s ); // s は print_string によって借用されますprint_string ( & s ); // s はまだ消費されていません。この関数を何度でも呼び出すことができます}これらの所有権ルールにより、Rust の型はアフィン型として知られており、各値は最大で 1 回しか使用できません。これにより、値の所有者がその正確性と解放に単独で責任を負うため、ソフトウェア障害の分離の一形態が強制されます。 [ 75 ]
値がスコープ外になると、デストラクタを実行して破棄されます。デストラクタは、トレイトを実装することでプログラム的に定義できます。オブジェクトが破棄されると、それに関連付けられたリソースが自動的に閉じられるか解放されるため、ファイルハンドル、ネットワークソケット、ロックなどのリソースの管理に役立ちます。 [ 76 ]Drop
オブジェクトのライフタイムとは、参照が有効な期間、つまりオブジェクトの作成から破棄までの期間を指します。[ 77 ]これらのライフタイムは、すべてのRust参照型に暗黙的に関連付けられています。多くの場合推論されますが、名前付きライフタイムパラメータ(多くの場合、、などと表記)を使用して明示的に指定することもできます。 [ 78 ]'a'b
Rust における値の有効期間は、変数が有効なソースコード内の位置 (関数、行、列番号など) のセットから推測されます。[ 79 ]例えば、ローカル変数への参照は、それが宣言された式から最後に使用されるまで有効です。[ 79 ]
fn main () { let mut x = 5 ; // ------------------+- ライフタイム 'a // | let r = & x ; // -+-- ライフタイム 'b | // | | println! ( "r: {}" , r ); // -+ | // r はもう使われていないので、 | // そのライフタイムは終了します | let r2 = & mut x ; // -+-- ライフタイム 'c | } // ------------------+Rustコンパイラの借用チェッカーは、参照が関連付けられたライフタイムが有効なソースコードの場所のみで使用されることを強制します。[ 80 ] [ 81 ]上記の例では、変数への参照をに格納することはx有効rです。なぜなら、変数のライフタイム( )は変数( )よりもx長いためです。しかし、のライフタイムが短い場合、借用チェッカーはプログラムを拒否します。'ar'bx
fn main () { let r ; // ------------------+- ライフタイム 'a // | { // | let x = 5 ; // -+-- ライフタイム 'b | r = & x ; // エラー: x は | | } // 十分に長く生きません -| | // | println! ( "r: {}" , r ); // | } // ------------------+参照される変数()の寿命が参照を保持する変数()の寿命よりも短いため、借用チェッカーがエラーを起こし、スコープ外からの使用が阻止されます。[ 82 ]'b'ax
関数引数に明示的なライフタイム パラメータを使用することで、ライフタイムを指定できます。たとえば、次のコードは、関数によって返される参照が と同じライフタイムを持つことを指定しますoriginal(必ずしも と同じライフタイムである必要はありませんprefix)。[ 83 ]
fn remove_prefix <' a > ( mut original : & ' a str , prefix : & str ) -> & ' a str { if original . starts_with ( prefix ) { original = original [ prefix . len () .. ]; } original }コンパイラでは、所有権とライフタイムが連携して、ダングリングポインタなどのメモリ安全性の問題を防止します。[ 84 ] [ 85 ]
ユーザー定義型は、structまたはenumキーワードを使用して作成されます。キーワードは、複数の関連する値をグループ化するレコード型structを示すために使用されます。 [ 86 ]は実行時にさまざまなバリアントを取ることができ、その機能は関数型プログラミング言語にある代数的データ型に似ています。 [ 87 ]レコードと列挙型の両方のバリアントには、異なる型のフィールドを含めることができます。[ 88 ]同じ型の別名、つまりエイリアスは、キーワードを使用して定義できます。[ 89 ]enumtype
キーワードimplは、ユーザー定義型のメソッドを定義できます。データと関数は別々に定義されます。実装は、他の言語におけるクラスと同様の役割を果たします。[ 90 ]

Rust標準ライブラリはVec、Option、 、などのコアデータ構造やスマートポインタHashMap型など、広く使用されている多くのカスタムデータ型を定義および実装しています。Rust は、組み込みデバイスなどのアプリケーション向けに、属性 を使用して標準ライブラリの大部分を除外する方法を提供しています。内部的には、標準ライブラリは 、 、、 の3 つの部分に分割されており、と はによって除外されます。[ 91 ]#![no_std]coreallocstdstdalloc#![no_std]
Rust はオプション型Option<T>を使用してオプション値を定義し、それを使用して一致させif let、match内部値にアクセスできます: [ 92 ]
fn main () { let name1 : Option <& str > = None ; // この場合、何も出力されませんif let Some ( name ) = name1 { println! ( "{name}" ); }let name2 : Option <& str > = Some ( "Matthew" ); // この場合、単語 "Matthew" が出力されます。if let Some ( name ) = name2 { println! ( "{name}" ); } }同様に、Rust の結果型はResult<T, E>、正常に計算された値 (Okバリアント) またはエラー (Errバリアント) を保持します。[ 93 ]と同様にOption、 の使用は、Result内部の値を直接使用できないことを意味します。プログラマは、式、 (「try」演算子)matchなどの構文糖衣、または明示的なアサーションを使用して、それにアクセスする必要があります。 と は両方とも標準ライブラリ全体で使用されており、エラーと欠落データの処理に対する Rust の明示的なアプローチの基本的な部分です。?unwrapOptionResult
および参照型は&、null ではなく有効なメモリを指すことが保証されています。[ 94 ]生ポインタ型およびは安全性の保証を除外するため、null または無効な場合があります。ただし、ブロックを使用してコードが明示的に安全でないと宣言されない限り、それらを逆参照することはできません。[ 95 ]逆参照とは異なり、生ポインタの作成は安全な Rust コード内で許可されています。[ 96 ]&mut*const*mutunsafe
Rust は、ほとんどのプリミティブ型間で暗黙的な型変換 (強制) を提供しません。ただし、キーワードを使用して明示的な型変換 (キャスト) を実行できますas。[ 97 ]
let x : i32 = 1000 ; println! ( "1000 を u16 で表すと: {}" , x as u16 );Rust は、トレイト、ジェネリック関数、およびトレイト オブジェクトを通じてポリモーフィズムをサポートしています。[ 98 ]
型間の共通の動作は、特性とimplブロックを使用して宣言されます。[ 99 ]
trait Zero : Sized { fn zero () -> Self ; fn is_zero ( & self ) -> bool where Self : PartialEq , { self == & Zero :: zero () } }impl Zero for u32 { fn zero () -> u32 { 0 } }impl Zero for f32 { fn zero () -> Self { 0.0 } }is_zero上記の例には、特性を実装する際にオーバーライドできるデフォルトの実装を提供するメソッドが含まれています。 [ 99 ]
関数をジェネリックにするには、山括弧 ( ) 内に型パラメータを追加します。山括弧は、特性を実装する型のみを許可します。<Num>
// zero は型パラメータ Num を 1 つ持つ汎用関数です。fn zero < Num : Zero > () -> Num { Num :: zero () }fn main ( ) { let a : u32 = zero (); let b : f32 = zero (); assert! ( a.is_zero ( ) && b.is_zero ( ) ); }上記の例では、およびは、またはを実装する型のみを許可するように型を制限するトレイト境界です。[ 99 ]トレイトまたは実装内では、コードが実装している型を指します。[ 100 ]Num:ZerowhereSelf:PartialEqZeroPartialEqSelf
ジェネリクスは、同じコードを繰り返すことなく、異なる型に対して動作を実装できるようにするために関数で使用できます(境界付きパラメトリック多相性を参照)。ジェネリック関数は、実際の型を知らなくても、他のジェネリクスに関連して記述できます。[ 101 ]
デフォルトでは、トレイトは静的ディスパッチを使用します。コンパイラは各具象型インスタンスに対して関数を単相化し、コンパイル時間が長くなりバイナリが大きくなるという代償を伴いますが、型固有のコードと同等のパフォーマンスが得られます。[ 102 ]
コンパイル時に正確な型がわからない場合、Rust はトレイト オブジェクト&dyn Traitとを提供しますBox<dyn Trait>。[ 103 ]トレイト オブジェクト呼び出しはルックアップ テーブルを介した動的ディスパッチを使用します。トレイト オブジェクトは、データ ポインタとメソッド テーブル ポインタの両方を保持する「ファット ポインタ」です。[ 102 ]この間接参照により実行時のコストがわずかに増加しますが、コードのコピーが 1 つに保たれ、バイナリ サイズが削減されます。トレイト オブジェクトとして使用できるのは、「オブジェクト セーフ」なトレイトのみです。[ 104 ]
このアプローチはダックタイピングに似ており、特定の特性を実装するすべてのデータ型は機能的に互換性があるとみなすことができます。[ 105 ]次の例では、各オブジェクトが特性を実装するオブジェクトのリストを作成しますDisplay。
use std :: fmt :: Display ;let v : Vec < Box < dyn Display >> = vec! [ Box :: new ( 3 ), Box :: new ( 5.0 ), Box :: new ( "hi" ), ];for x in v { println! ( "{x}" ); }リスト内の要素がDisplay特性を実装していない場合、コンパイル時エラーが発生します。[ 106 ]
Rust はガベージ コレクションを使用しません。メモリやその他のリソースは、代わりに「リソースの取得は初期化である」という規約[ 107 ]とオプションの参照カウントによって管理されます。Rust は、非常に低いオーバーヘッドで決定論的なリソース管理を提供します。[ 108 ]値はデフォルトでスタック上に割り当てられ、すべての動的割り当ては明示的に行う必要があります。[ 109 ]
シンボルを使用する組み込みの参照型は、&実行時の参照カウントを伴いません。基となるポインタの安全性と有効性はコンパイル時に検証され、ダングリングポインタやその他の未定義の動作を防ぎます。[ 110 ] Rust の型システムは、形式の共有された不変の&T参照と、形式の一意の可変の参照を分離します&mut T。可変の参照は不変の参照に強制できますが、その逆はできません。[ 111 ]
Rust のメモリ安全性チェック ( #Safetyunsafeを参照)は、ブロックを使用することで回避できます。これにより、プログラマは任意の生ポインタを逆参照したり、外部コードを呼び出したり、安全な Rust では許可されていないその他の低レベル機能を実行したりできます。 [ 112 ]この方法で有効になる低レベル機能には、 volatile メモリへのアクセス、アーキテクチャ固有の組み込み関数、型パンニング、インラインアセンブリなどがあります。[ 113 ]
例えば、データ構造の実装では、安全でないコードが必要になります。[ 114 ]よく引用される例として、安全なRustで二重リンクリストを実装するのは困難または不可能です。 [ 115 ] [ 116 ] [ 117 ] [ 118 ]
安全でない Rust を使用するプログラマは、例えば同じ場所を指す可変参照が 2 つ存在しないなど、Rust のメモリと型の安全性の要件を遵守する責任があるとみなされます。[ 119 ]プログラマがこれらの要件に違反するコードを書いた場合、未定義の動作が発生します。[ 119 ] Rust のドキュメントには、ダングリング ポインタやアラインメントがずれたポインタへのアクセス、参照のエイリアス ルールの違反など、未定義とみなされる動作のリストが含まれています。[ 120 ]
マクロを使用すると、Rust コードの生成と変換によって繰り返しを減らすことができます。マクロには 2 つの形式があり、を介して定義される宣言型マクロmacro_rules!と、別のクレートで定義される手続き型マクロがあります。[ 121 ] [ 122 ]
宣言型マクロ(「例によるマクロ」とも呼ばれる)は、macro_rules!キーワードを使用して定義され、パターンマッチングを使用して展開を決定するマクロです。[ 123 ] [ 124 ]以下は、すべての引数を合計する例です。
macro_rules! sum { ( $initial : expr $(, $expr : expr ) * $(, ) ? ) => { $initial $( + $expr ) * } }fn main () { let x = sum ! ( 1 , 2 , 3 ); println! ( "{x}" ); // 6 と表示される}この例では、という名前のマクロsumは、の形式で定義されていますmacro_rules! sum {(...) => { ... } }。定義の括弧内の最初の部分であるマクロパターンは、マクロ( $initial:expr $(, $expr:expr )* $(,)? )が受け取ることができる入力の構造を指定します。ここで、$initial:exprは最初の式を表し、は、$(, $expr:expr )*その後にカンマで区切られた式が0個以上続く可能性があることを意味します。末尾のにより、$(,)?呼び出し元はエラーを発生させることなく、オプションで最後のカンマを含めることができます。矢印の後の2番目の部分は=>、マクロが呼び出されたときに生成されるコードについて説明します。この場合、は、$initial $(+ $expr)*生成されるコードが最初の式から始まり、に続き+、追加の式が順番に続くことを意味します。は*、再び「このパターンを0回以上繰り返す」ことを意味します。つまり、マクロが後で8行目でとして呼び出されると、sum!(1, 2, 3)マクロは、1 + 2 + 3渡されたすべての式の合計を表すに解決されます。
手続き型マクロは、他のコンポーネントがコンパイルされる前にコンパイラの入力トークンストリームを実行して変更する Rust 関数です。一般的に宣言型マクロよりも柔軟性がありますが、その複雑さゆえに保守がより困難です。[ 125 ] [ 126 ]
手続き型マクロには、次の3種類があります。
custom!(...)#[derive(CustomDerive)]#[custom_attribute]Rust はキーワードを使用して外部関数インターフェース(FFI)の作成をサポートしていますextern。C呼び出し規約を使用する関数はを使用して記述できます。シンボルは属性を使用して Rust から他の言語にエクスポートでき、シンボルはブロックを使用して Rust にインポートできます。[注 6 ] [ 128 ]extern"C"fn#[unsafe(no_mangle)]extern
#[unsafe(no_mangle)] pub extern "C" fn exported_from_rust ( x : i32 ) -> i32 { x + 1 } unsafe extern "C" { fn imported_into_rust ( x : i32 ) -> i32 ; }この属性により、FFI境界を越えて使用できるsとs#[repr(C)]の決定論的なメモリレイアウトが可能になります。 [ 128 ]やなどの外部ライブラリは、C/C++用のRustバインディングを生成できます。[ 128 ] [ 129 ]structenumbindgencxx
Rust が保証する安全性には、メモリ安全性、型安全性、データ競合の回避が含まれます。上記のように、これらの保証はunsafeキーワードを使用することで回避できます。
メモリの安全性には、ヌルポインタ、ダングリングポインタ、アラインメントがずれたポインタへの逆参照がないこと、バッファオーバーフローやダブルフリーエラーがないことが含まれます。[ 130 ] [ 131 ] [ 132 ] [ 133 ]
安全な Rust ではメモリ リークが発生する可能性があります。 [ 134 ]メモリ リークは、互いを指す参照カウント ポインタ (参照サイクル) の作成の結果として発生する可能性があります[ 134 ]または、呼び出しによって意図的に作成することもできますBox::leak。[ 135 ]
Rust エコシステムには、コンパイラ、標準ライブラリrustup、およびソフトウェア開発のための追加コンポーネントが含まれます。コンポーネントのインストールは通常、Rust プロジェクトによって開発されたRustツールチェーンインストーラである によって管理されます。 [ 136 ]
Rustコンパイラはrustc、Rustコードをバイナリにコンパイルします。まず、コンパイラはソースコードをASTに解析します。次に、このASTはIRにダウングレードされます。その後、コンパイラのバックエンドがサブコンポーネントとして呼び出され、最適化を適用して、結果として得られたIRをオブジェクトコードに変換します。最後に、リンカを使用してオブジェクトを単一の実行可能イメージに結合します。[ 137 ]
rustc はデフォルトでLLVM をコンパイラ バックエンドとして使用しますが、GCCやCraneliftなどの代替バックエンドの使用もサポートしています。[ 138 ]これらの代替バックエンドの目的は、Rust のプラットフォーム カバレッジを拡大するか、コンパイル時間を短縮することです。[ 139 ] [ 140 ]

CargoはRustのビルドシステムおよびパッケージマネージャーです。公式レジストリで管理されているパッケージ(クレートと呼ばれる)をダウンロード、コンパイル、配布、アップロードします。また、Clippyやその他のRustコンポーネントのフロントエンドとしても機能します。[ 141 ]
デフォルトでは、Cargo はユーザーが提供したレジストリcrates.ioから依存関係を取得しますが、Gitリポジトリ、ローカル ファイルシステム内のクレート、その他の外部ソースも依存関係として指定できます。[ 142 ]
Cargo は、Cargo.toml と Cargo.lock という 2 つのメタデータ ファイルを通じて再現可能なビルドをサポートします。[ 143 ] Cargo.toml は、使用される各パッケージとそのバージョン要件を宣言します。Cargo.lock は依存関係の解決中に自動的に生成され、推移的依存関係を含むすべての依存関係の正確なバージョンを記録します。[ 144 ]
Rustfmt はRust 用のコード フォーマッタです。特に指定がない限り、一般的なスタイルに従ってコードを生成するように空白とインデントをフォーマットします。スタンドアロン プログラムとして、または Cargo を介して Rust プロジェクトから呼び出すことができます。[ 145 ]

Clippyは、Rustコードの正確性、パフォーマンス、可読性を向上させるためのRustに組み込まれたリンティングツールです。 2026年現在800以上のルールがあります。[ 146 ] [ 147 ]
Rust 1.0以降、新機能は毎日リリースされるナイトリーバージョンで開発されています。6週間ごとのリリースサイクルでは、ナイトリーバージョンの変更がベータ版にリリースされ、前のベータ版の変更が新しい安定版にリリースされます。[ 148 ]
2~3年ごとに新しい「エディション」がリリースされます。エディションは、 async/await機能をサポートするためにキーワードを昇格させるなど、限定的な破壊的変更を可能にするためにリリースされます。異なるエディションを対象とするクレートは相互運用できるため、呼び出し元や依存関係が古いエディションを対象としていても、クレートは新しいエディションにアップグレードできます。新しいエディションへの移行は、自動化されたツールによって支援できます。[ 149 ]await
rust-analyzer は、言語サーバープロトコルを介して統合開発環境(IDE) やテキストエディタに Rust プロジェクトに関する情報を提供するユーティリティ群です。これにより、コード編集時にオートコンプリートやコンパイルエラー表示などの機能が利用可能になります。[ 150 ]
Rust はガベージ コレクションを行わないため、他のメモリ安全な言語よりも高速な場合が多い。[ 151 ] [ 75 ] [ 152 ] Rust のメモリ安全性の保証のほとんどは実行時のオーバーヘッドを伴わないが、[ 153 ]デフォルトでは実行時にチェックされる配列インデックスは例外である。 [ 154 ]配列インデックスの境界チェックのパフォーマンスへの影響は様々だが、場合によってはかなり大きくなる可能性がある。[ 154 ]
Rust の多くの機能は、いわゆるゼロコスト抽象化であり、コンパイル時に最適化されて削除されるため、実行時のペナルティは発生しません。[ 155 ]所有権と借用システムにより、解析などのパフォーマンスに影響されるタスクの一部でゼロコピー実装が可能になります。[ 156 ]静的ディスパッチは、動的特性オブジェクトで呼び出されるメソッドを除き、メソッド呼び出しをデフォルトで排除するために使用されます。 [ 157 ]コンパイラは、関数呼び出しと静的にディスパッチされたメソッド呼び出しを排除するためにインライン展開を使用します。[ 158 ]
CやC++とは異なり、Rustでは表現属性が適用されない限り、コンパイラが構造体や列挙型の要素を並べ替えることができます#[repr(C)]。[ 159 ]これにより、場合によってはコンパイラがより効率的なコードを生成できます。[ 160 ]

ウェブサービスでは、Ciscoが所有するDNS解決サービスであるOpenDNSは、内部で Rust を使用しています。[ 162 ] [ 163 ] Amazon Web Services は、サービスの「パフォーマンスに敏感なコンポーネント」で Rust を使用しています。2019 年に、AWS は主に Rust で書かれた仮想化ソリューションであるFirecracker をオープンソース化しました。[ 164 ] IoTデバイスで Azure サービスを実行するために使用されるプラットフォームであるMicrosoft Azure IoT Edgeには、Rust で実装されたコンポーネントがあります。[ 165 ] Microsoft は、 WebAssemblyとKubernetesを使用してコンテナ化されたモジュールを実行するためにも Rust を使用しています。[ 166 ]コンテンツ配信ネットワークサービスを提供するCloudflare は、パフォーマンスと効率を向上させるために、Pingora という名前の新しいウェブプロキシを構築するために Rust を使用しました。[ 167 ] npmパッケージマネージャは、 2019 年に本番認証サービスに Rust を使用しました。[ 168 ] [ 169 ] [ 170 ]

オペレーティングシステムでは、Linuxカーネルは、Rust for Linuxプロジェクトの一環として、2022年後半にバージョン6.1でRustコードの実験的サポートを導入し始めました。[ 171 ] [ 172 ] [ 173 ] Rustで書かれた最初のドライバはバージョン6.8に含まれました。[ 171 ] 2025年、Linuxカーネル開発者サミットでカーネル開発者たちは、このプロジェクトが成功したと判断し、カーネルコードでのRustの使用はもはや実験的とは見なされなくなりました。[ 174 ] Android開発者は2021年にRustを使用して既存のコンポーネントを書き換えました。[ 175 ] [ 176 ] MicrosoftはWindowsの一部をRustで書き換えました。[ 177 ] r9プロジェクトは、ベル研究所のPlan 9をRustで再実装することを目的としています。[ 178 ] Rust は、Unix ライクなオペレーティングシステムおよびマイクロカーネルであるRedox、[ 179 ]モジュール型状態管理を備えた実験的なオペレーティングシステムである Theseus、[ 180 ] [ 181 ]およびFuchsiaの大部分などの新しいオペレーティングシステムの開発にも使用されています。[ 182 ] Rust は、ファイルシステムマネージャであるstratisd [ 183 ] [ 184 ]やSystem76のデスクトップ環境であるCOSMIC [ 185 ]などのコマンドラインツールおよびオペレーティングシステムコンポーネントにも使用されています。
Web開発では、JavaScriptとTypeScriptのセキュアなランタイムであるDenoが、 RustとTokioを使用してV8上に構築されています。 [ 186 ]この分野で注目すべき採用例としては、オープンソースのSWFエミュレータであるRuffle [ 187 ]や、オープンソースのブロックチェーンおよび暗号通貨プラットフォームであるPolkadot [ 188 ]などがあります。Servoブラウザエンジン( MozillaとSamsungが出資)のコンポーネントは、Firefoxの基盤となるGeckoブラウザエンジンに組み込まれました。[ 189 ] 2023年1月、Google(Alphabet )は、 ChromiumでサードパーティのRustライブラリを使用することをサポートすると発表しました。[ 190 ] [ 191 ]
その他の用途としては、インスタントメッセージングソフトウェア企業のDiscordが、2020年にパフォーマンス向上のためシステムの一部をRustで書き直した。同年、Dropboxはファイル同期をRustで書き直したと発表した。Facebook (Meta )は、社内プロジェクトのソースコードを管理するシステムを再設計するためにRustを使用した。[ 20 ]
2025 年のStack Overflow開発者調査では、回答者の 14.8% が最近 Rust で大規模な開発を行ったと回答しました。[ 192 ]この調査では、既存の開発者のうち、引き続き Rust で作業することに関心のある人の数に基づいて、2016 年から 2025 年 (両年を含む) まで毎年 Rust を「最も賞賛されているプログラミング言語」に挙げました。[ 193 ] [注 7 ] 2025 年には、現在 Rust で作業していない開発者の 29.2% が、Rust で作業することに関心を示しました。[ 192 ]
Rustの安全性とパフォーマンスは、プログラミング言語の研究で調査されている。[ 194 ] [ 114 ] [ 195 ]
他の分野では、国際天文学連合の論文集に掲載された論文で、Rust を使用して多惑星系をシミュレートした例がある。[ 196 ] Natureに掲載された論文では、バイオインフォマティクス研究者が Rust を使用している事例が紹介されている。[ 141 ]どちらの論文も、Rust のパフォーマンスと安全性を利点として挙げ、学習曲線が Rust の採用における主な欠点であるとしている。
2025年のDARPAプロジェクトTRACTORは、静的解析、動的解析、大規模言語モデルなどの技術を使用してC言語をRustに自動的に変換することを目指しています。[ 197 ]

MIT Technology Reviewによると、Rustコミュニティは新規参加者に対して「非常に友好的」であり、特にクィアコミュニティの人々を惹きつけており、その理由の一つは行動規範にあるとされています。[ 20 ]包括性は、一部のRust開発者にとって重要な要素として挙げられています。[ 141 ]公式のRustブログは、毎年人口統計データを収集して公開しています。[ 200 ]
Rust Foundationは、米国で設立された非営利の会員制組織であり、Rustの商標、インフラストラクチャ、および資産を管理しています。[ 202 ] [ 46 ]
2021年2月8日に設立され、5社の創設企業メンバー(Amazon Web Services、Huawei、Google、Microsoft、Mozilla)が参加した。[ 203 ]財団の理事会はシェーン・ミラーが議長を務め、[ 204 ]アシュリー・ウィリアムズが暫定事務局長を務めた。[ 46 ] 2021年後半には、レベッカ・ランブルが事務局長兼CEOに就任した。[ 205 ]
Rustプロジェクトは、2025年11月現在、 8つのトップレベルのチームによって維持管理されている。: リーダーシップ評議会、コンパイラチーム、開発ツールチーム、インフラストラクチャチーム、言語チーム、ローンチパッド、ライブラリチーム、モデレーションチーム。[ 206 ]リーダーシップ評議会はプロジェクトを監督し、他のチームからの代表者によって構成されます。[ 207 ]
no_mangleunsafeextern"C"unsafeスタイルに詳しい方は、更新された
--explain
メッセージがElmのアプローチから大きな影響を受けていることに気づくかもしれません。
これらは、Rust プログラミング言語の所有権型と借用ポインタに触発されています。
どちらも中括弧言語で、C に似た構文のため、C プログラマーにとって敷居が低い。
チェックされたインデックス付けのオーバーヘッドには大きなばらつきが見られます。ベンチマークの 23.6% はチェックされたインデックス付けによるパフォーマンスの大幅な低下を報告していますが、64.5% はほとんど影響がないと報告しており、驚くべきことに 11.8% はパフォーマンスが向上したと報告しています。
... 一部のコンパイラ(Rustなど)は構造の並べ替えをサポートしていますが[82]、CおよびC++コンパイラはデータ構造(構造体やクラスなど)の並べ替えを禁止しています[74] ...