Rust プログラミング言語。 Rust: Mozilla スペシャリストによる新しいプログラミング言語の使用を開始

09.10.2021 アンドロイド



現在、Rust 構文は、コンパイラーに付属の構文ファイルを使用して vim および emacs でサポートされています。
人気の専用エディタ Sublime Text 2 や無料エディタ Kate の構文パッケージもあります。 IDE ではまだ Rust がサポートされていません。 デバッガのサポートもないようです。

次のユーティリティは、rustc コンパイラに付属しています。
> ラストドック- Doxygen のようなソース コードからドキュメントを自動的に生成するユーティリティ。
> 錆びた- 追加のパッケージやライブラリを簡単にインストールできるパッケージ マネージャー。
> 錆びた- いわゆる REPL ユーティリティ (read-eval-print-loop)。 これは本質的には、コマンド ラインから Rust 式を取得し、それを内部 LLVM 表現にコンパイルし、実行して、結果を出力するテスト インタプリタです。
> さび- パラメータに応じて他のユーティリティまたはコンパイラを起動するユニバーサル ユーティリティ。 私にとっては決してうまくいきませんでした。

この言語に関する利用可能なドキュメントはすべて、公式 Web サイト www.rust-lang.org に収集されています。 詳細なマニュアル (http://static.rust-lang.org/doc/tutorial.html) があります。これは、構文、メモリ モデル、ランタイム システムなどのすべてのニュアンスに関する包括的な正式なドキュメントと、組み込みコア ライブラリと標準ライブラリ std。 すべてのドキュメントは英語です。 ロシア語の最新資料はなく、既存のレビュー記事のいくつかはすでに非常に時代遅れです。

イデオロギーと構文


Rust は C に似た言語で、中括弧を使用してコードのブロックを区切ります。 この言語は「マルチパラダイム」です。 命令型手続き型、オブジェクト指向型、同時実行型、または関数型の方法でコードを作成できます。 Rust は、サポートされているプラ​​ットフォーム (バックエンドとして LLVM を使用) 上でネイティブ バイナリ コードにコンパイルします。 理論的には、Rust コードは C/C++ コードと同じくらい高速である必要があります。 Rust はシステム言語として位置付けられていますが、「真の」システム言語 C、C++、D のようなアセンブリ コード ブロックのサポートは組み込まれていません。

Rust のメモリ モデルは本質的に、null ポインタやダングリング ポインタ、バッファ オーバーフローを許可しません。 1 つのコード スレッド内でのみ機能するオプションのガベージ コレクターがあります。 この言語には、軽量のマルチタスクと、メッセージングを使用したスレッド間の通信のサポートが組み込まれています。 Rustには共有メモリはまったく存在しません。 すべての変数はスタック変数、特定のスレッドのヒープ変数、およびいわゆる「交換」ヒープ変数に分割されます。これらはすべてのスレッドで読み取ることができますが、変更することはできません。 これにより、マルチスレッド プログラミングの悩みの種と考えられているデッドロックが自動的に排除されます。 この言語の ABI は C と互換性があるため、追加のラッパーなしで Rust プログラムを C で書かれたライブラリにリンクできます。 低レベルのシステム プログラミングのニーズに対応し、C との互換性を確保するために、この言語にはポインターの正確性をチェックしない特別な「安全でない」モードがあります。 そのイデオロギーにおいては、Rust は Go 言語に最も近いです。 Go と同様に、マルチスレッド プログラミングの単純さと大規模なアプリケーションの開発速度が主に重視されており、構文も珍しく、いくつかの場所でやや驚くべきものになります。 同時に、Rust は Go ほどミニマルではなく、システム言語であると主張しています。

Rust の構文は主に C と C++ から借用されており、Go、C#、Haskell、Python、Ruby からのアイデアがいくつか組み込まれています。 この言語の構文を徹底的に説明するつもりはありませんが、最も興味深い概念のみに焦点を当てます。

さびは、Mozilla によって開発されている新しい実験的なプログラミング言語です。 この言語はコンパイル済みのマルチパラダイムであり、C/C++ の代替として位置付けられていますが、競争相手がそれほど多くないため、それ自体興味深いものです。 Walter Bright の D や Google の Go を思い出してください。
Rust は、関数型、並列型、手続き型、オブジェクト指向のプログラミングをサポートしています。 アプリケーション プログラミングで実際に使用されるパラダイムのほぼすべての範囲。

私の目標はドキュメントを翻訳することではなく (さらに、この言語はまだ正式にリリースされていないため、ドキュメントは非常に希少であり、常に変更されています)、その代わりに、この言語の最も興味深い機能を強調したいと考えています。 情報は、公式ドキュメントと、インターネット上のこの言語に関するごくわずかな言及の両方から収集されました。

第一印象

この言語の構文は、伝統的な C のようなスタイルで構築されています (これはすでに事実上の標準であるため、これは朗報です)。 当然のことながら、よく知られている C/C++ 設計エラーは考慮されています。
従来の Hello World は次のようになります。
標準を使用します。 fn main(args: ) ( std::io::println("hello world from " + args + "!"); )

もう少し複雑な例 - 階乗計算関数:

Fn fac(n: int) -> int ( let result = 1, i = 1; while i<= n { result *= i; i += 1; } ret result; }

例からわかるように、関数は「関数型」スタイルで宣言されます (このスタイルには、従来の「int fac(int n)」よりもいくつかの利点があります)。 私たちは見る 自動型推論(let キーワード)、while 引数に括弧はありません (Go と同じ)。 もう 1 つすぐに目を引くのは、キーワードのコンパクトさです。 Rust の作成者は、すべてのキーワードをできる限り短くすることに本当に気を配っていました。正直に言うと、私はそれが気に入っています。

小さいながらも興味深い構文上の特徴

  • 数値定数にアンダースコアを挿入できます。 これは便利な機能であり、現在多くの新しい言語に追加されています。
    0xffff_ffff_ffff_ffff_ffff_ffff
  • バイナリ定数。 もちろん、本物のプログラマーは頭の中で bin を 16 進数に変換する必要がありますが、この方法の方が便利です。 0b1111_1111_1001_0000
  • ステートメントの本体は (単一の式で構成されている場合でも) 中括弧で囲む必要があります。 たとえば、C では if(x>0) foo(); と書くことができます。 、Rust では foo() を中かっこで囲む必要があります。
  • ただし、if、while、および類似の演算子の引数を括弧で囲む必要はありません。
  • 多くの場合、コードのブロックは式として考えることができます。 特に、次のことが可能です。
    let x = if the_stars_align() ( 4 ) else if something_else() ( 3 ) else ( 0 );
  • 関数宣言構文 - 最初に fn キーワード、次に引数のリスト。名前の後に引数の型が示され、関数が値を返す場合は矢印「->」と戻り値の型が示されます。
  • 変数も同様に宣言されます。キーワード let、変数の名前、変数の後にコロンで型を指定し、初期値を割り当てます。
    カウントしてみましょう: int = 5;
  • デフォルトでは、すべての変数は不変です。 mutable キーワードは、可変変数を宣言するために使用されます。
  • 基本型の名前は、私が見つけた中で最もコンパクトです: i8、i16、i32、i64、u8、u16、u32、u64、f32、f64
  • 前述したように、自動型推論がサポートされています。
この言語にはプログラム デバッグ ツールが組み込まれています。
キーワード 失敗現在のプロセスを終了します
キーワード ログ任意の言語表現をログ (標準エラー出力など) に出力します。
キーワード 主張する式をチェックし、それが false の場合は、現在のプロセスを終了します。
キーワード 注記プロセスが異常終了した場合に追加情報を表示できます。

データ型

Rust は Go と同様にサポートします 構造的型付け(ただし、著者によると、これらの言語は独自に開発されたため、これは共通の前任者であるAlef、Limboなどの影響です)。 構造型付けとは何ですか? たとえば、何らかのファイル (Rust 用語では「レコード」) で宣言された構造があるとします。
タイプポイント = (x: 浮動小数点、y: 浮動小数点);
「ポイント」引数タイプを使用して、多数の変数と関数を宣言できます。 次に、別の場所で、次のような別の構造体を宣言できます。
type MySuperPoint = (x: 浮動小数点、y: 浮動小数点);
この型の変数は、point 型の変数と完全な互換性があります。

対照的に、C、C++、C#、および Java で採用されている主格型付けでは、そのような構成は許可されません。 主格型付けの場合、各構造は固有の型であり、デフォルトでは他の型と互換性がありません。

Rustでは構造体を「レコード」と呼びます。 タプルもあります。これらは同じレコードですが、名前のないフィールドがあります。 レコードの要素とは異なり、タプルの要素は変更できません。

ベクトルがあります。ある意味では通常の配列に似ており、ある意味では stl の std::vector 型に似ています。 リストで初期化する場合、C/C++ のような中括弧ではなく、角括弧が使用されます。

myvec = ; とします。

ただし、ベクトルは動的データ構造であり、特にベクトルは連結をサポートします。

v: 可変 = ; とします。 v += ;

テンプレートがあります。 これらの構文は非常に論理的であり、C++ の「テンプレート」の煩雑さはありません。 関数とデータ型のテンプレートがサポートされています。

Fn for_rev (v: [T], act: block(T)) ( let i = std::vec::len(v); while i > 0u ( i -= 1u; act(v[i]); ) ) 型円形バッファ = (開始: uint、終了: uint、buf: );

この言語はいわゆる タグ。 これは、C の共用体に、使用されるバリアントのコード (つまり、共用体と列挙型の共通点) という追加フィールドを備えたものにすぎません。 または、理論的な観点からは、代数データ型。

タグの形状 (円(ポイント, フロート); 長方形(ポイント, ポイント); )

最も単純なケースでは、タグは列挙型と同一です。

動物にタグを付けます (犬; 猫;) a: 動物 = 犬; とします。 a = 猫。
より複雑な場合は、「列挙」の各要素は、独自の「コンストラクター」を持つ独立した構造になります。
もう 1 つの興味深い例は、「リスト」タイプのオブジェクトを定義するために使用される再帰構造です。
タグリスト ( nil; cons(T, @list ); ) リストを作成してみましょう = cons(10, @cons(12, @nil));
タグはパターン マッチング式に参加できますが、これは非常に複雑になる場合があります。
alt x ( cons(a, @cons(b, _)) ( process_pair(a,b); ) cons(10, _) ( process_ten(); ) _ ( 失敗; ) )

パターンマッチング

まず、マッチング パターンを改良されたスイッチと考えることができます。 alt キーワードが使用され、その後に分析対象の式が続き、ステートメントの本文でパターンとパターンが一致する場合のアクションが使用されます。
alt my_number ( 0 ( std::io::println("zero"); ) 1 | 2 ( std::io::println("1 つまたは 2"); ) 3 ~ 10 ( std::io::println ("3 から 10") ) _ ( std::io::println("何か他のもの"); ) )
「パターン」として、定数 (C の場合など) だけでなく、より複雑な式 (変数、タプル、範囲、型、プレースホルダー (「_」) など) も使用できます。 パターンの直後に when ステートメントを使用して、追加の条件を指定できます。 型一致のための演算子の特別なバリアントがあります。 これが可能なのは、言語にユニバーサル バリアント型があるためです。 どれでも、そのオブジェクトには任意の型の値を含めることができます。

ポインタ。通常の「C」ポインタに加えて、Rust は参照カウントが組み込まれた特別な「スマート」ポインタ - 共有 (共有ボックス) と固有 (ユニーク ボックス) をサポートします。 これらは、C++ のshared_ptr および unique_ptr に似ています。 これらには独自の構文があります。 @ は共有、~ は一意です。 一意のポインタの場合、コピーの代わりに、移動という特別な操作があります。
x = ~10 とします。 させてください<- x;
このような移動の後、x ポインタは初期化されません。

クロージャ、部分アプリケーション、イテレータ

ここから関数型プログラミングが始まります。 Rust は、高階関数、つまり他の関数を引数として受け取り、それを返すことができる関数の概念を完全にサポートしています。

1. キーワード ラムダネストされた関数または関数データ型を宣言するために使用されます。

Fn make_plus_function(x: int) -> lambda(int) -> int ( lambda(y: int) -> int ( x + y ) ) let plus_two = make_plus_function(2); plus_two(3) == 5; をアサートします。

この例では、int 型の引数 "x" を 1 つ取り、"int->int" 型の関数を返す関数 make_plus_function があります (ここでは lambda がキーワードです)。 関数本体はまさにこの関数を記述します。 「return」演算子がないのは少し混乱しますが、これは FP にとっては一般的なことです。

2. キーワード ブロック関数型、つまり関数の引数を宣言するために使用され、通常のコードのブロックに似たものに置き換えることができます。
fn map_int(f: block(int) -> int, vec: ) -> ( let result = ; for i in vec ( result += ; ) ret result; ) map_int((|x| x + 1 ), );

ここには、入力がブロックである関数があります。これは本質的に「int->int」型のラムダ関数と int 型のベクトルです (ベクトルの構文については後で詳しく説明します)。 「ブロック」自体は、少し特殊な構文 (|x| x + 1) を使用して呼び出しコードに記述されます。 個人的には、C# のラムダ、記号 | の方が好きです。 ビット単位の OR として永続的に認識されます (ちなみに、古い C ベースの演算と同様、Rust にも存在します)。

3. 部分適用とは、別の関数の引数の一部の値を指定して、より多くの引数を持つ別の関数に基づいた関数を作成することです。 これに使われるキーワードは、 練るおよびプレースホルダー文字「_」:

daynum = binding std::vec::position(_, ["mo", "tu", "we", "do", "fr", "sa", "su"]) とします。

わかりやすくするために、これは次のような単純なラッパーを作成することで通常の C で実行できることをすぐに言います。
const char* daynum (int i) ( const char *s =("mo", "tu", "we", "do", "fr", "sa", "su"); return s[i]; )

ただし、部分適用は関数型スタイルであり、手続き型ではありません (ちなみに、与えられた例からは、部分適用を実行して引数なしで関数を取得する方法は明確ではありません)。

別の例: add 関数は 2 つの int 引数で宣言され、int を返します。 次に、関数型 single_param_fn が宣言されます。これは 1 つの引数 int を持ち、int を返します。 バインドを使用すると、2 つの関数オブジェクト add4 と add5 が宣言され、部分的に引数が指定された add 関数に基づいて構築されます。

Fn add(x: int, y: int) -> int (ret x + y; ) type single_param_fn = fn(int) -> int; let add4: single_param_fn = バインド add(4, _); let add5: single_param_fn = バインド add(_, 5);

関数オブジェクトは、通常の関数と同じ方法で呼び出すことができます。
アサート (add(4,5) == add4(5)); アサート (add(4,5) == add5(4));

4. 純粋関数と述語
純粋関数とは、副作用のない関数です (純粋関数以外の関数を呼び出さない関数も含みます)。 このような関数は、pure キーワードによって識別されます。
pure fn lt_42(x: int) -> bool ( ret (x< 42); }
述語は bool 型を返す純粋な関数です。 このような関数は typestate システム (以下を参照) で使用できます。つまり、さまざまな静的チェックのためにコンパイル段階で呼び出されます。

構文マクロ
予定されている機能ですが、非常に便利です。 Rust ではまだ開発初期段階にあります。
std::io::println(#fmt("%s は %d", "答え", 42));
C の printf に似た式ですが、コンパイル時に実行されます (したがって、すべての引数エラーはコンパイル段階で検出されます)。 残念ながら、構文マクロに関する資料はほとんどなく、マクロ自体も開発中ですが、ネメルマクロのようなものが世に出てくることが期待されています。
ちなみに、Nemerle とは異なり、私は # 記号を使用してマクロを構文的に強調表示する決定は非常に賢明であると考えています。マクロは関数とは大きく異なるエンティティであり、一目でどこにあるかがわかることが重要だと思います。コード関数が呼び出され、マクロが呼び出されます。

属性

C# の属性に似た概念 (構文も似ています)。 開発者の方々に心より感謝申し上げます。 ご想像のとおり、属性は、注釈を付けたエンティティにメタ情報を追加します。
# fn register_win_service() ( /* ... */ )
属性構文の別のバリアントが考案されました。同じ行ですが、最後にセミコロンがあり、現在のコンテキストに注釈が付けられます。 つまり、そのような属性を囲む最も近い中括弧に一致するものです。
fn register_win_service() ( #; /* ... */ )

並列コンピューティング

おそらく、この言語の最も興味深い部分の 1 つです。 同時に、現時点ではチュートリアルではまったく説明されていません:)
Rustのプログラムは「タスクツリー」で構成されています。 各タスクには、入力関数、独自のスタック、他のタスクとの対話手段 (送信情報用のチャネルと受信情報用のポート) があり、動的ヒープ内のオブジェクトの一部を所有します。
単一のオペレーティング システム プロセス内に複数の Rust タスクが存在できます。 Rust タスクは「軽量」です。各タスクの消費メモリは OS プロセスよりも少なく、タスク間の切り替えは OS プロセス (ここではおそらく「スレッド」を意味します) 間の切り替えよりも高速です。

タスクは、引数のない少なくとも 1 つの関数で構成されます。 タスクは spawn 関数を使用して起動されます。 各タスクは、他のタスクに情報を送信するチャネルを持つことができます。 チャネルは特別なテンプレート タイプの chan であり、チャネル データ タイプによってパラメータ化されます。 たとえば、chan は符号なしバイトを送信するためのチャネルです。
チャネルに送信するには、send 関数を使用します。この関数の最初の引数はチャネル、2 番目の引数は送信する値です。 この関数は実際に値をチャネルの内部バッファに置きます。
ポートはデータを受信するために使用されます。 ポートは、ポート データ タイプによってパラメータ化された汎用ポート タイプです。ポートは、符号なしバイトを受信するためのポートです。
ポートから読み取るには、recv 関数を使用します。この関数の引数はポートであり、戻り値はポートからのデータです。 読み取りはタスクをブロックします。つまり、 ポートが空の場合、タスクは、別のタスクがそのポートに関連付けられたチャネルにデータを送信するまで待機状態になります。
チャネルとポートの関連付けは非常に簡単です。 chan キーワードを使用してチャネルをポートで初期化します。
reqport = port(); にします。
reqchan = chan(reqport); とします。
複数のチャネルを 1 つのポートに接続できますが、その逆はできません。1 つのチャネルを同時に複数のポートに接続することはできません。

タイプステート

「タイプステート」という概念のロシア語への一般に受け入れられている翻訳が見つからないので、それを「タイプステート」と呼ぶことにします。 この機能の本質は、静的型付けで採用されている通常の型チェックに加えて、コンパイル段階で追加のコンテキスト チェックが可能であることです。
何らかの形で、型の状態はすべてのプログラマにとって馴染みのあるものです。コンパイラ メッセージによれば、「変数は初期化なしで使用されます」とのことです。 コンパイラは、一度も書き込まれていない変数が読み取られている場所を検出し、警告を発行します。 より一般的な形式では、このアイデアは次のようになります。すべてのオブジェクトには、それが取り得る一連の状態があります。 各状態は、そのオブジェクトに対する有効な操作と無効な操作を定義します。 また、コンパイラは、オブジェクトに対する特定の操作がプログラム内の特定の場所で許可されているかどうかを確認できます。 これらのチェックはコンパイル時に実行することが重要です。

たとえば、「ファイル」タイプのオブジェクトがある場合、「閉じた」状態と「開いた」状態を持つことができます。 また、ファイルが閉じられている場合、ファイルからの読み取り操作は許可されません。 現代の言語では、読み取り関数が例外をスローするか、エラー コードを返すのが一般的です。 型状態システムはコンパイル時にそのようなエラーを検出する可能性があります。コンパイラが変数の読み取り操作が書き込み操作の前に発生すると判断するのと同じように、「ファイル オープン」状態で「読み取り」メソッドが有効であると判断する可能性があります。 、オブジェクトをこの状態に転送する「Open」メソッドの前に呼び出されます。

Rust には「述語」という概念があります。これは副作用がなく、bool 型を返す特別な関数です。 このような関数は、特定の条件の静的チェックを目的として、コンパイル段階で呼び出されるコンパイラーによって使用されます。

制約は、コンパイル時に実行できる特別なチェックです。 これには check キーワードが使用されます。
pure fn is_less_than(int a, int b) -< bool { ret a < b; } fn test() { let x: int = 10; let y: int = 20; check is_less_than(x,y); }
次の方法で、述語を関数の入力パラメータに「掛ける」ことができます。
fn テスト(int x, int y) : is_less_than(x,y) ( ... )

typestate については情報が少なく、まだ不明な点も多いですが、とにかくコンセプトが面白いです。

それだけです。 まだいくつかの興味深い点を見逃している可能性は十分にありますが、記事はすでに肥大化していました。 必要に応じて、Rust コンパイラを構築して、さまざまな例を試してみることができます。 アセンブリ情報は次の場所で提供されます。



親愛なる読者の皆さん、こんにちは!

人生は静止していないので、オライリーは Rust プログラミング言語に関する最初の基本的な本を出版することを考えました。

このトピックに興味を持った私たちは、2014 年 12 月に公開された Rust 言語に関するレビュー記事の翻訳を議論の対象にすることにしました。 一部の文章がすでに古くなっているという事実のため、この記事はわずかに短くされていますが、著者はこの言語を既存の代替案と照らし合わせてよく検討し、その(無条件の)利点と(条件付きの)欠点を強調しています。

ただし、さらに面白くするために、この記事のコメントに、お気に入りのロシア語プログラミング ブログの 1 つで公開されている Rust に関する別の記事へのリンクを残しましょう。 まず、猫に行きます。

免責事項: この投稿と同様、プログラミング言語の好みは非常に主観的な問題です。 健全な懐疑心を持って受け止めてください.

最近、いくつかの新しいプログラミング言語が登場しました。 その中でも私が特に興味を持ったのがRustでした。 以下では、Rust に対する私の印象を共有し、他のいくつかのプログラミング言語と比較します。

Rust学習の障壁

初めての試みでは Rust のことを知ることができませんでした。 この言語の学習には、次のようないくつかの障壁があります。

  1. 言語は急速に変化している。 Rust には「終身善良な独裁者」は存在しません。 この言語は、コア チーム メンバーとコミュニティの貢献を通じて進化します。
  2. 最初の点を考慮すると、 Rustのチュートリアルは非常に少ない。 マニュアル、その他の公式ドキュメント、および Rust by Example Web サイトは素晴らしいリソースです。 ただし、Rust ははるかに複雑です。 多くの場合、必要な情報を見つけるために RFC、ブログ、さらには Github のコメントをくまなく調べなければなりません。たとえこの情報が昨日公開されたとしても、まだ完全に確信が持てているわけではありません。 きっと長くなると思いますが、Rust に関する信頼できる優れた本を楽しみにしています。
  3. Rust の所有権システムと借用チェックのメカニズムは初心者にとって混乱を招く可能性があります。 ガベージコレクションを行わずにメモリの安全性を確保するために、Rust は借用と所有権の複雑なシステムを使用します。 彼女はよく初心者を怖がらせて追い払ってしまいます。
  4. Rust コンパイラは非常に厳密です。 私はRustを規律言語と呼んでいます。 Rust コンパイラにとって完全に明らかではないものはすべて自分で指定する必要があり、意図の一部は最初は自分自身でも気づいていない可能性があります。 この学習の壁は、他のすべての障害と同様に、多くの場合、Rust に対する落胆的な第一印象をもたらします。

利点

Rustには多くの利点があります。 そのうちのいくつかはユニークです。

ガベージコレクションを使用しないメモリの安全性

これはおそらく Rust の最も重要な成果です。 メモリの直接操作が可能な低レベルのプログラミング言語では、解放後の使用や実行時のメモリ リークなどのエラーが非常に高くつきます。 最新の C++ では、このような問題に対処する能力は向上していますが、それには厳格な技術規律が必要です (プログラマーは安全でない操作を実行し続けています)。 したがって、私の意見では、一般的に C++ ではこの問題を根本的に確実に解決することはできません。

確かに、Rust プログラマは安全でないコードを安全でないブロックに書き込むことができますが、(1) これは意図的に行われており、(2) 安全でないブロックはコード ベース全体のごく一部しか構成していない可能性がありますが、厳密に管理されています。
ガベージ コレクターは、最も一般的なメモリ安全ツールです。 GC を使いこなすことができれば、かなり多くの選択肢があります。 ただし、Rust の所有権システムはメモリのセキュリティだけでなく、データとリソースのセキュリティも保証します (下記を参照)。

RAII とリソース

RAII (リソースの取得は初期化です) は奇妙な用語ですが、その考えはよく伝わってきます。 Wikipedia では、RAII はスタック上に割り当てられたオブジェクトを処理すると書かれています。 Rust の所有権システムでは、この原則をヒープに割り当てられたオブジェクトにも適用できます。 これにより、メモリ、ファイル、ソケットなどのリソースの自動解放が非常に予測可能になり、コンパイル時に保証されます。
Python や Ruby などの動的言語にも同様の機能がありますが、Rust IMO の能力には及びません。

データ競合のない競争力

Rust は、同時プログラミング中のデータのセキュリティを保証します。つまり、一度に多数のリーダーまたは 1 人の「ライター」だけがデータにアクセスできるようにします。

代数データ型

通常の型 (タプルと構造体) に加えて、Rust は列挙型 (ここでは「合計型」または「バリアント型」と呼びます) とパターン マッチングも提供します。 システムプログラミング言語にこれほど発達した型システムがあることは驚きです。

継承よりも構成

Rust は明らかに継承よりも型合成を優先します。 私はこの事実が勝利とみなされる陣営にいます。 Rust がジェネリック型をサポートする場合、トレイトが重要な役割を果たします。

デメリット(条件付き)

すべてが非常に明確でなければなりません

Rust は規律ある言語です。 コンパイラーは、すべてを非常に明確に伝える必要があります。そうしないと、不明瞭な点がなくなるまで罵倒されます。 これは通常、コードの品質に役立ちますが、ラピッド プロトタイピングや 1 回限りのタスクに関しては過剰になる可能性があります。

結果として、Rust でより適切で明確なコードを記述する必要があります。 これを理解すると、粗さは多かれ少なかれ解消されます。

ガベージコレクションは二次的なものです

Rust には非常に基本的なガベージ コレクターがあります。Rc (参照カウント) と Arc (ラウンド ロビン検出なしのアトミック参照カウント) です。 ただし、これらの機能はデフォルトでは言語で動作しないため、Rust の標準メモリ管理メカニズム (Stack、&、および Box) をより頻繁に使用する必要があります。 アプリケーションのメモリ問題が重大でない場合は、ガベージ コレクションを使用しない Rust のメモリ安全モデルを許容する必要があります。

表現すること自体が目的ではない

Rust 言語はコードの表現力や美しさを気にしません。 その点では決して悪くはありませんが、期待するほど素晴らしいものではありません。

参入障壁が比較的高い

原則として、Rust は数週間ですぐにマスターしてプロフェッショナルなコードを作成できる言語ではありません。 Rust はおそらく C++ よりもコンパクトですが、多くのプログラミング言語よりも大きいのは間違いありません。 他の言語と比較すると、決して親しみやすい言語とは言えません。 言語習得速度を優先する場合、これは問題になる可能性があります。

Rust とその他の言語

動的言語

動的 (スクリプト) 言語は、プログラミング言語スペクトルの Rust の対極にあります。 Rust と比較すると、動的言語でのコードの作成は通常、より高速かつ簡単です。 私は、次のような状況では動的言語が Rust に勝ると思います。

  • ラピッドプロトタイピングまたは単発タスク
  • コードが実稼働用ではない、または実行時のエラーが小さな問題になるようなコードではない
  • 独自の(個人の)プロジェクト
  • 半自動作業 (例: ログの解析/分析、バッチテキスト処理)

このような場合、すべてを完璧にやろうとする必要はありません。 それどころか、私の意見では、Rust は次のような用途に適しています。

  • 中規模または大規模なチームで働く
  • 本番環境での長期使用を目的としたコード指向
  • 長期間使用されるコードには定期的なメンテナンスやリファクタリングが必要です
  • 安全性を確保するために多くの単体テストを作成するコード

一般に、コードの品質が重要な場合。 動的言語を使用すると、初期段階ではコードをより速く書くことができますが、その後は作業が遅くなり、より多くのテストを作成する必要が生じたり、開発ラインが中断されたり、本番環境で中断が発生したりすることもあります。 Rust コンパイラは、コンパイル時に多くのことを正しく実行することを強制します。このとき、バグを特定して修正する方がコストがかかりません。

行く

これら 2 つの言語を比較することは議論の絶好の理由ですが、私はしばらく勉強しているので、ここではまだこの言語についての私の主観的な印象を共有します。 Rust と比較して、私が Go で気に入っている点は次のとおりです。

  • 軽量 - 言語は小さい (シンプルですが非常に強力です)
  • gofmt ユーティリティ – プログラミング時の精神的負荷を大幅に軽減します
  • ゴルーチン/チャネル
  • インスタントコンパイル

Goをやめた理由:

  • ミニマルすぎます。 型システムと言語自体はあまり拡張性がありません
  • Go プログラミングは私にとって少しドライに思えます。 Java でプログラミングしていた頃のことを思い出します。エンタープライズ開発には適していますが、機械的で、あまり面白くありません (注意: 好みについては議論の余地はありません)
  • Google のサポートのおかげで Go の人気は続いていますが、それは少し懐疑的です。 コミュニティと会社の利益が一致しない場合、最初の利益が犠牲になる可能性があります。 もちろん、どの企業も主に自社の利益を追求します。 何も問題はありません。 ただ…ちょっと面倒なんです。 (企業が推進する多くの言語やフレームワークも同様の問題に直面しています。少なくとも Mozilla は株価に依存しません。)

ニム

Nim (以前は Nimrod と呼ばれていました) は非常に興味深い言語です。 C にコンパイルされるため、パフォーマンスは非常に優れています。 外見上は、私がずっとプログラミングが好きだった言語である Python に似ています。 これはガベージ コレクション言語ですが、ソフト リアルタイム サポートを提供し、ガベージ コレクター自体の動作はより予測可能です。 面白いエフェクトシステムを搭載しています。 基本的に私はこの言語がとても好きです。

彼の場合の最大の問題は、エコシステムの未熟さだ。 言語自体はよく構築されており、比較的安定していますが、現時点では、プログラミング言語が成功するには十分とは言えません。 ドキュメント、標準ライブラリ、パッケージ リポジトリ、サポート フレームワーク、コミュニティおよびサードパーティの参加...すべてを本番環境に向けて準備するのは簡単ではありません。

フルタイムで言語を完成させる専門家がいないと、この最後の段階は非常に厳しいものになる可能性があります。 新しいプログラミング言語の中で、Nim はまだ本格的なサポートを誇ることができません。
そうは言っても、私は彼の成功を祈り、彼をフォローし続けます。

その他

他にも Julia や などの言語があります。 Julia は、優れたパフォーマンスとスムーズな C スタイルの呼び出しを備えた動的言語です (動的言語と REPL が好きな場合は注意してください)。 Julia は、数値および科学分野のおかげでみんなの注目を集めています。 汎用言語になる可能性を秘めていますが、言語の発展はその開発者のコ​​ミュニティに大きく影響されるように思えます。

D は、少なくとも当初は、「C++ より優れたもの」を作成する試みでした。 バージョン 1.0 は 2007 年にリリースされたため、この言語はそれほど新しいものではありません。 これは優れた言語ですが、客観的な理由によりまだ根付いていません。その理由は、初期段階で Phobos/Tango に分割されたこと、主にガベージ コレクションを通じてメモリの安全性が提供されていること、および初期の位置付けが、Phobos/Tango の代替であることです。 C++。

Rust の可能性が非常に高いと私が考える理由

最近では、非常に多くの新しいプログラミング言語が登場しています。 私の意見では、Rust がそれらの中で際立っている理由は何でしょうか? 私は次のような議論をします。

システムプログラミングのための実際の言語

埋め込みは簡単な作業ではありません。 おそらく、文字通り複数の言語、あるいは C と C++ の 2 つの言語で解決できるかもしれません。 (これが、非常にリスクがあったにもかかわらず、Skylight が Ruby の拡張機能を開発するために Rust を選択した理由かもしれません。) Rust が実行時のオーバーヘッドをいかにうまく排除できたかは注目に値します。 これにより、Rust に独自の視点が開かれます。

Nullなし

Null オブジェクト/ポインター (いわゆる「10 億ドル規模のバグ」) は、ランタイム エラーの一般的な原因です。 null を持たないプログラミング言語はわずかで、ほとんどが関数型言語です。 重要なのは、null を取り除くには非常に高度な型システムが必要であるということです。 通常、言語の構文レベルでこれに対処するには、代数データ型とパターン マッチングが必要です。

高度な高レベル構造を備えた低レベル言語

Rust は、(少なくとも理論的には)コアまで「ベアメタル言語」であるため、代数データ型、パターンマッチング、トレイト、型推論などを含む、比較的高レベルの機能を多数提供します。

強力なコミュニティと実用的な関連性

Rust コミュニティは非常にフレンドリーで活発です。 (もちろん主観的な感想です)。 さらに、Rust はいくつかの本格的な実用的なプロジェクト、特に Rust コンパイラ、Servo、Skylight などで使用されています。 まだ言語発達の段階です。

これまでのところ、大きなエラーはありません

企業内で行われる言語やフレームワークの開発は、ときに偶然行き詰まりに陥ることがあります。 幸いなことに、Rust のコアチームはこれまでのところ素晴らしい仕事をしています。 頑張れ、ラスト!

Web開発のためのRust

Rust がシステム プログラミング言語である場合、Web 開発には適していますか? この質問に対する答えも探しています。

ライブラリとフレームワーク

まず、いくつかの HTTP ライブラリがこれに対応できるように準備されている必要があります。 (これについては、Web サイト「Are we web Yet」で説明されています)。 最初の Rust-http ライブラリはすでに時代遅れです。 彼女の後継者となる可能性のあるティピーは事実上仮死状態にある。 幸いなことに、Hyper が良い候補のようです。 これはすでに Rust の共生プロジェクトである Servo に受け入れられており、これが Rust の HTTP ライブラリであることは幸いだと思います。

Rust 標準ライブラリはまだ非同期 I/O をサポートしていません。 この目的のために、ノンブロッキング ソケット I/O を提供する外部 mio ライブラリを使用できます。 I/O 簡素化の一環として、グリーン スレッドのサポートが削除されました。

Iron や nickel.rs など、Rust 用のいくつかの Web フレームワークが積極的に開発されています。 彼らの状況が落ち着くまでには時間がかかるかもしれない。

Rust は Web 用の言語ですか?

いつかライブラリとフレームワークが完成するでしょう。 問題は、Rust 自体が Web 開発に適しているかということです。 Rust の低レベルのメモリ管理とセキュリティ機能は複雑すぎますか?

結局のところ、すべてはプロジェクトに何を期待するかによって決まると思います。 上で、短期プロジェクトで Rust を動的言語と比較する場合、そのような場合には Rust の複雑さが正当化されない可能性があると述べました。 しかし、製品が長期間 (たとえば 6 か月以上) 続くと予想される場合は、Rust が良い選択肢になるかもしれません。

Rust は Web スタートアップに適していますか?

スタートアップ企業についてはどうでしょうか? 迅速なプロトタイピングと開発サイクルが必要です。 これはより物議を醸す質問ですが、私は私の意見を支持します。長期的なプロジェクトを検討している場合、適切なプログラミング言語を選択することが重要であり、Rust は特別な注目に値します。 ビジネスの観点から見ると、ラピッド プロトタイピングを可能にする言語には大きなメリットがありますが、リファクタリングやボトルネックの解消は常に後回しにされる可能性があります。 エンジニアリングの現実として、リファクタリング作業のコストは通常​​、思っているよりも高く、システムの多くの要素を変更したとしても、ずっと前に書かれたコードはまだ片隅に残っています。 長年。

Rustを試してみよう!

サイトの開発に資金を寄付したり送金したりできます



Federico Mena-Quintero による記事の翻訳。彼は Miguel de Icaza とともに、主に GNU/Linux システム用に広く使用されている無料のグラフィック環境である GNOME プロジェクトを設立しました。 これに先立って、彼はしばらく GIMP をサポートしていました。 Federico は現在、Rust プログラミング言語を使用して librsvg ライブラリを積極的に開発しています。 彼の意見では、開発は、いくつかの大きなコンポーネントを C から Rust に移植する方が、単純にアクセサを追加するよりも簡単な作業であるように見える段階に達しています。 Federico は C から Rust に切り替えたり、またその逆に戻ったりすることがよくあります。その記事の中で、C が現代のソフトウェアにとって非常に非常に原始的な言語であると考える理由について語っています。

Cのための一種のエレジー

私は約 24 年前に C プログラミング言語に夢中になりました。 私はカーニハン/リッチー著『The C Programming Language (K&R)』第 2 版のスペイン語訳を読んで基本を学びました。 その前は、ポインターと手動メモリ割り当てを使用して、かなり低レベルの方法で Turbo Pascal を作成していました。 それはCにさわやかで力強い気分を与えました。

K&R は、その文体と簡潔なプログラミングにより、優れた本です。 この本では、単純な malloc/free 関数の実装方法も説明されており、非常に有益です。 言語の一部のように見える低レベルの構成要素でも、言語自体に実装できます。

それから数年で、私は C に習熟しました。C は小さな標準ライブラリを備えた単純な言語です。 おそらく、20,000 行程度のコードで Unix カーネルを実装するには理想的な言語でした。

GIMP と GTK+ は、C で派手なオブジェクト指向アプローチを使用する方法を私に教えてくれました。GNOME は、C で書かれた大規模なプロジェクトをサポートする方法を私に教えてくれました。20,000 行の C コードは、ほぼ完全に理解できるプロジェクトであるように感じ始めました数週間以内に。

しかし、私たちのコードベースはもはやそれほど小さくありません。 現在ソフトウェア開発中です 巨大な言語の標準ライブラリで利用可能な関数に期待しています。

Cの使用経験

ポジティブ

  • POV-Ray プロジェクトのソース コードを初めて読み、純粋な C でのオブジェクト指向アプローチと継承の使用方法を学びます。
  • GTK+ プロジェクトのソース コードを読み、読みやすく、保守しやすく、クリーンな C コーディング スタイルを学びます。
  • SIOD プロジェクトのソース コードと初期の Guile プロジェクトのソース コードを読み、C で Scheme インタープリターを記述する方法を理解します。
  • Eye of Gnome の最初のバージョンを作成し、マイクロタイル レンダリング システムを完成させます。

ネガティブ

  • プログラムが頻繁にクラッシュしていたとき、Evolution チームで働いていました。 Purify を購入するには、Solaris を搭載した車を購入する必要がありました。 当時、Valgrind はまだ存在していませんでした。
  • gnome-vfs でのスレッドのデッドロックのデバッグ。
  • Mesa のデバッグが失敗しました。
  • Nautilus-share の最初のバージョンのソース コードを渡されたとき、free() がまったく使用されていないことがわかりました。
  • メモリ管理戦略がまったく分からなかったコードをリファクタリングしようとしました。
  • グローバル変数が多数あり、 static としてマークされている関数が 1 つも存在しないコードからライブラリを作成しようとする試み。

C にはない Rust の機能

自動リソース管理

私が Rust について読んだ最初のブログ投稿の 1 つは、「Rust ではソケットを閉じる必要はありません」というものでした。 Rust は、イディオム (リソースの取得は初期化) とスマート ポインターに関する C++ のアイデアを借用し、値の唯一の所有権を追加し、非常にエレガントなパッケージで自動かつ決定論的なリソース管理のメカニズムを提供します。

  • 自動: free() を手動で呼び出す必要はありません。 変数がスコープ外になると、メモリが解放され、ファイルが閉じられ、ミューテックスのロックが解除されます。 サードパーティ リソースのラッパーを作成する必要がある場合、必要なのは Drop 特性を実装することだけです。 ラップされたリソースは、その存続期間を手動で管理する必要がないため、言語の一部のように感じられます。
  • 決定的: リソースは作成され (メモリの割り当てと初期化、ファイルのオープンなど)、スコープ外になると破棄されます。 ガベージ コレクションなし: かっこを閉じるとリソースが実際に解放されます。 プログラム内のデータの有効期間が関数呼び出しのツリーとして認識され始めます。

C でオブジェクトを解放/クローズ/破棄することを常に忘れたり、さらに悪いことに、他の人のコードのどこでこれらを実行するのを忘れたのか (または誤って実行したのか) を見つけようとした後、 二度)…もうこれはいりません。

ジェネリック

ベク 実際には、要素のサイズが T 型のオブジェクトのサイズと等しいベクトルです。 これは、メモリが個別に割り当てられたオブジェクトへのポインタの配列ではありません。 これは、型 T のオブジェクトのみを操作できるコードに特別にコンパイルされます。

似たようなことをするために C で疑わしいマクロをたくさん書いた後...もう使いたくない。

特性は単なるインターフェースではありません

Rust は Java のようなオブジェクト指向言語ではありません。これについては、オープンソースの書籍「The Rust Programming Language」を参照してください。 代わりに、最初は Java のインターフェースに似た特性を持ち、動的ディスパッチを実装する簡単な方法です。そのため、オブジェクトが Drawable を実装している場合は、draw() メソッドがあると想定できます。

ただし、型はより強力なツールです。 特性の際立った特徴の 1 つは、関連タイプと考えることができます。 たとえば、Rust は実装できる Iterator トレイトを提供します。

Pub trait Iterator ( type item; fn next(&mut self) -> オプション ; }

これは、この特性を反復可能なオブジェクトに実装するときは常に、それが生成する値の項目タイプも指定することを意味します。 next() を呼び出してまだ要素が残っている場合は、 Some(YourElementType) を取得します。 イテレータの要素がなくなると、 None が返されます。

関連する型は他の型を参照できます。

たとえば、Rust では、IntoIterator トレイトを実装するものであれば for ループを使用できます。

Pub trait IntoIterator ( /// 反復処理する要素のタイプ type item; /// どのタイプのイテレータに変換しますか? type IntoIter: Iterator ; fn into_iter(self) -> Self::IntoIter; )

この特性を実装するときは、イテレータが生成する要素のタイプと、Iterator 特性を実装してイテレータの状態を保存する IntoIter タイプ自体の両方を指定する必要があります。

このようにして、相互に参照するタイプの実際のネットワークを構築できます。 「私は foo と bar を実行できますが、これとこれを実行できる型を与えてもらった場合に限ります。」という型を書くことができます。

スライス

C には文字列を操作するためのスライスが不足していることと、文字列を手元に置くことに慣れていると頭痛の種になることについてはすでに書きました。

依存関係管理のための最新ツール

の代わりに

  • pkg-config を手動で実行するか、Autotools マクロを通じて実行します。
  • ヘッダー ファイル内のインクルード パスとの戦い...
  • ...そしてライブラリファイル。
  • そして実際には、正しいバージョンのライブラリがインストールされていることをユーザーが保証する必要があります。

すべての依存関係の名前とバージョンをリストする Cargo.toml ファイルを作成します。 これらは、公知のソースまたはお客様が指定したその他のソースからダウンロードされます。

依存症と戦う必要はありません。 カーゴ build と入力すると機能します。

テスト

C では、次のような理由から、コードをテストでカバーすることは非常に困難です。

  • 多くの場合、内部関数は静的としてマークされます。 これは、関数が定義されているファイルの外では関数を呼び出すことができないことを意味します。 テスト プログラムは、関数が宣言されているソースの内容を #include するか、テスト時にのみ #ifdef を使用して静的を削除するかのいずれかを強制されます。
  • テスト プログラムを主要な依存関係の特定の部分、またはプログラムの残りの部分とリンクするには、Makefile を操作する必要があります。
  • テスト フレームワークを選択する必要があります。 テストをテスト フレームワークに登録する必要があります。 そうする必要があります 勉強この枠組み。

Rust では次のように書きます。

# fn test_that_foo_works() (assert!(foo() == Expect_result); )

プログラムまたはライブラリのどこにいても、「cargo test」と入力すると、正常に動作します。 このコードはテスト実行可能ファイルにのみリンクされます。 手作業で 2 回コンパイルしたり、Makefile マジックを書いたり、テスト用に内部関数を引き出す方法を考えたりする必要はありません。

私にとって、これはこの言語の主なキラー機能の 1 つです。

テストを含むドキュメント

Rust は、Markdown を使用してマークアップされたコメントに基づいてドキュメントを生成します。 ドキュメントからのコード 通常のテストと同じように実行されます。 関数をテストするときに関数をどのように使用するかを示すことができます。

/// 指定された数値を 2 倍します /// /// ``` ///assert_eq!(multiply_by_two(5), 10); /// ``` fn multiply_by_two(x: i32) -> i32 ( x * 2 )

サンプル コードは、ドキュメントがプログラム コードに合わせて最新の状態に保たれていることを確認するテストとして実行されます。

衛生的なマクロ

Rust には、C マクロを展開するときにコード内で識別子が意図せず隠される問題を回避するための特別な衛生マクロがあります。 max(5 + 3, 4) が正しく動作するために、すべての文字を括弧で囲むマクロを作成する必要はなくなりました。

暗黙的な型キャストはありません

int を short や char などに意図せずキャストすることによって C で発生するこれらすべてのバグは、Rust には存在しません。 型を明示的にキャストする必要があります。

整数オーバーフローなし

それがすべてを物語っています。

通常、セーフ モードでは未定義の動作はありません

Rustでは、何かが「セーフモード」(unsafe()ブロックの外側に書かれたもの)で未定義の動作を引き起こす場合、それは言語自体のバグとみなされます。 たとえば、負の整数をビット単位で右にシフトすると、期待どおりの結果が得られます。

パターンマッチング

enum で switch() を使用しても、すべてのオプションが処理されない場合、gcc がどのように警告するかご存知ですか? Rustに比べたら幼稚園だよ。

Rust ではさまざまな場所でパターン マッチングが使用されます。 彼は、一致式の列挙を使用してこれを行うことができます。 構造化をサポートしています。つまり、関数から複数の値を返すことができます。

Impl f64 ( pub fn sin_cos(self) -> (f64, f64); ) let angle: f64 = 42.0; let (sin_angle, cos_angle) = angle.sin_cos();

match は文字列に対して機能します。 クソみたいなラインを一致させることができます。

color = "緑" にします。 色を一致させる ( "red" => println!("これは赤")、 "green" => println!("これは緑")、 _ => println!("何か他のもの")、 )

これを読むのがどれほど難しいか知っていますか?

my_func(true、false、false)

代わりに、関数の引数にパターン マッチングを使用してみてはいかがでしょうか。

Pub struct Fubarize(pub bool); pub struct Frobnify(pub bool); pub struct Bazificate(pub bool); fn my_func(Fubarize(fub): Fubarize, Frobnify(frob): Frobnify, Bazificate(baz): Bazificate) ( if fub ( ...; ) if frob && baz ( ...; ) ) ... my_func(Fubarize (true)、Frobnify(false)、Bazificate(true));

標準の便利なエラー処理

これについて詳しく説明しました。 適切なエラー説明のないブール値の戻り値はもう必要ありません。エラーが誤って無視されることも、longjmp 例外処理も必要ありません。

#

新しい型 (たとえば、多数のフィールドを持つ構造体) を作成する場合、 # を記述すると、Rust はデバッグ用にその型の内容を自動的に出力する方法を認識します。 カスタム タイプ フィールドの内容を表示するためだけに、特別な関数を手動で記述して gdb から呼び出す必要はなくなりました。

クロージャ

関数ポインターと user_data を手動で渡す必要はなくなりました。

結論

私は、コンパイラがマルチスレッド コードでのデータ競合を防止できる「フィアレス コンカレンシー」をまだ試していません。 これは、定期的に並列コードを書く人にとっては大きな変革になると思います。

C は、原始的な構造と原始的なツールを備えた古い言語です。 これは、信頼できるアカデミック環境で実行される小規模なシングルプロセッサ Unix カーネルに最適でした。 しかし、それは最新のソフトウェアには適していません。

Rust を学ぶのは簡単ではありませんが、学ぶ価値があると確信しています。 課題は、この言語を使用するには、作成するコードを深く理解する必要があることです。 これは、より優れたプログラマーになり、より野心的な問題を解決できる言語の 1 つだと思います。

そこで、最近誕生日を迎えた男の子(2016 年 5 月 15 日に 1 歳になりました)、Rust をご紹介したいと思います。 これは Mozilla によって開発されたユニバーサル プログラミング言語であり、その 3 つの主な原則は、速度、セキュリティ、人間工学です。 作成者自身も、これが C/C++ の後継となる可能性が最も高いものの 1 つであると控えめに考えています。 StackOverflow の調査によると、Rust は現在開発者の間で最もお気に入りの言語です。 それでは、それが何であるかを詳しく見てみましょう。

初心者向けの錆び

誰も騙したくないので、ここに責任ある発言をします: Rust を学ぶのは非常に難しいです。 第一に、これは言語の若さ、そしてその結果としての文学の量の少なさによるものです。 第二に、プログラミングから遠く離れた人の方が、他の言語に精通している人よりもプログラミングを学ぶのがさらに簡単である可能性があります。 したがって、たとえば、既製の IT スペシャリストは、わずかな操作を規定する必要があることに非常に悩まされるでしょうし、言語に継承そのものが存在しないと、単純に混乱するだけです。

ただし、Rust は急速に発展しており (新しいリリースは 6 週間ごとにリリースされます)、コミュニティも成長しており、インターネットで情報を見つけることはもはや難しくありません。

勉強方法

必要なものはほぼすべて公式ウェブサイトで見つけることができます。 さらに、Rust フォロワーのコミュニティは非常に大規模でフレンドリーなので、いつでも IRC (ロシア語セクションあり) や公式フォーラムにアドバイスを求めることができます。 また、電子書籍を含む書籍も少しずつ出始めました。 その品質を評価するのはまだ難しいですが、これは事実です。

知り合いになるための初期段階を過ぎた人にとっては、RFC やコミットなど、GiHub で役立つ資料がたくさん見つかります。 さらに、直接参加するか、少なくとも今年下半期に予定されている Rust カンファレンスの 1 つの Web キャストを視聴することができます。 カレンダーは次のとおりです。

  • 9月9日~10日、米国ポートランドで開催されるRustConfカンファレンス。
  • 9月17日、ドイツのベルリンで開催されたRustFestヨーロッパコミュニティカンファレンス。
  • 10 月 27 日 米国ピッツバーグでの Rust Belt Rust カンファレンス。

さて、Rust を自分の天職と考えている人々に会い、同時に彼らのあらゆる知恵を求めるには、モスクワの言語ファンの集会の主催者や参加者に連絡することができます。

特徴

前に述べたことを少し繰り返して、Rust 言語の主な長所と短所を強調します。

長所:

  • 記憶力のある安全な作業。
  • ハイパフォーマンス;
  • 代数データ型。
  • コンパイルの予測可能性。

マイナス点:

  • 一部のコードの冗長性。
  • 言語発達の集中度が高く、その結果、研究に適した適切な文献が不足している。
  • コンパイル用のパラメーターを明確かつ明確に指定する必要性。

実際、継承を能力に置き換えるなど、違いにはすぐに慣れます。 目が慣れ、手が慣れるとすぐに、Rust は完全に機能する言語に変わります。C++ よりもシンプルで機能的ですが、「美しさ」では他の多くのプログラミング言語に劣ります。 実際、Rust とその競合他社や以前のバージョンとの主な違いは、速度とセキュリティです。

要求

現在、Rust はゲーム、グラフィックス、オペレーティング システムの開発者の間で人気があります。 しかし、明らかな理由により、高度に専門化された Rust 専門家が必要とされる定常的な場所の数は世界でも非常に少なく、ロシアではさらに顕著です。 しかし、この言語が忘却の彼方に沈む兆候はまだなく、むしろ組織的に世界を乗っ取っているように見えます。 これは、将来、Rust を使用する優れたスキルがあれば、国内外で高収入で興味深い仕事を見つけるのに役立つことを意味します。

まだ需要がある:職業「」。