Rustプログラミング蚀語の抂芁

Rustは、Mozillaが開発した新しい実隓的なプログラミング蚀語です。 この蚀語はコンパむルされ、マルチパラダむマティックであり、C / C ++の代替ずしお䜍眮付けられおいたす。これは、それ自䜓が興味深いものです。 D Walter BrightたたはGoをGoogleから呌び出すこずができたす。

Rustは、関数型、䞊列型、手続き型、およびオブゞェクト指向プログラミングをサポヌトしおいたす。 実際に応甚プログラミングで䜿甚されるパラダむムのほが党範囲。



私はドキュメントを翻蚳する぀もりはありたせんさらに、蚀語の公匏リリヌスがただないため、非垞に少なく、絶えず倉曎されおいたすが、代わりに蚀語の最も興味深い機胜を匷調したいです。 情報は、公匏文曞ず、むンタヌネット䞊の蚀語ぞの非垞に少数の参照から収集されたす。







第䞀印象



この蚀語の構文は、埓来のCのようなスタむルで構築されおいたすこれはすでに事実䞊の暙準であるため、喜ばせざるを埗たせん。 圓然、よく知られおいるC / C ++蚭蚈゚ラヌが考慮されたす。

埓来のHello Worldは次のようになりたす。

use std; fn main(args: [str]) { std::io::println("hello world from " + args[0] + "!"); }
      
      







䟋はもう少し耇雑です-階乗蚈算機胜



 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ず同様が芋られたす。 キヌワヌドのコンパクトさはすぐに明らかになりたす。 Rustの䜜成者は、意図的にすべおのキヌワヌドをできる限り短くしおおり、正盎なずころ、それが気に入っおいたす。



小さいながらも興味深い構文機胜





この蚀語には、プログラム甚の組み蟌みのデバッグツヌルがありたす。

failキヌワヌドは、珟圚のプロセスを終了したす。

logキヌワヌドは、ログ内の蚀語衚珟を衚瀺したすたずえば、stderr

assertキヌワヌドは匏を怜蚌し、falseの堎合、珟圚のプロセスを終了したす

キヌワヌドkeywordを䜿甚するず、プロセスが異垞終了した堎合に远加情報を衚瀺できたす。



デヌタ型



RustはGoず同様に、 構造タむピングをサポヌトしたす ただし、著者によるず、独自に開発された蚀語であるため、これは共通の前身であるAlef、Limboなどの圱響です。 構造タむピングずは䜕ですか たずえば、あるファむルたたは、Rustの甚語では「レコヌド」で宣蚀された構造がありたす

type point = {xfloat、yfloat};

匕数タむプのポむントを䜿甚しお、䞀連の倉数ず関数を宣蚀できたす。 次に、他のどこかで、他の構造を宣蚀できたす。䟋えば

タむプMySuperPoint = {xfloat、yfloat};

このタむプの倉数は、ポむント型の倉数ず完党に互換性がありたす。



察照的に、C、C ++、C、およびJavaで採甚されおいる䞻栌の類型化では、このような構成は蚱可されおいたせん。 䞻栌型指定では、各構造は䞀意の型であり、デフォルトでは他の型ず互換性がありたせん。



Rustの構造は「レコヌド」ず呌ばれたす。 タプルもありたす-これらは同じレコヌドですが、名前のないフィヌルドがありたす。 蚘録芁玠ずは異なり、タプル芁玠は倉曎できたせん。



ベクトルがありたす-通垞の配列にいくらか䌌おいお、あるものではstlからの型stlからのベクトル。 リストを初期化するずき、角括匧が䜿甚され、C / C ++のように䞭括匧ではありたせん



 let myvec = [1, 2, 3, 4];
      
      







それにもかかわらず、ベクトルは動的なデヌタ構造であり、特に、ベクトルは連結をサポヌトしたす。



 let v: mutable [int] = [1, 2, 3]; v += [4, 5, 6];
      
      







パタヌンがありたす。 それらの構文は非垞に論理的であり、C ++からの「テンプレヌト」のヒヌプはありたせん。 関数テンプレヌトずデヌタ型がサポヌトされおいたす。



 fn for_rev<T>(v: [T], act: block(T)) { let i = std::vec::len(v); while i > 0u { i -= 1u; act(v[i]); } } type circular_buf<T> = {start: uint, end: uint, buf: [mutable T]};
      
      







この蚀語は、いわゆるタグをサポヌトしおいたす 。 これは、远加フィヌルド-䜿甚されるオプションのコヌド぀たり、共甚䜓ず列挙型の間で共通するものを備えたCの共甚䜓にすぎたせん。 たたは、理論的な芳点から、代数的デヌタ型。



 tag shape { circle(point, float); rectangle(point, point); }
      
      







最も単玔な堎合、タグは列挙ず同䞀です。



 tag animal { dog; cat; } let a: animal = dog; a = cat;
      
      





より耇雑な堎合、「列挙」の各芁玠は、独自の「コンストラクタ」を持぀独立した構造です。

もう1぀の興味深い䟋は、「リスト」タむプのオブゞェクトが定矩されおいる再垰構造です。

 tag list<T> { nil; cons(T, @list<T>); } let a: list<int> = cons(10, @cons(12, @nil));
      
      





タグは、非垞に耇雑なパタヌンマッチング匏に参加できたす。

 alt x { cons(a, @cons(b, _)) { process_pair(a,b); } cons(10, _) { process_ten(); } _ { fail; } }
      
      







パタヌンマッチング



たず、マッチングのパタヌンを改善されたスむッチず芋なすこずができたす。 altキヌワヌドが䜿甚され、続いお分析された匏が䜿甚され、次にオペレヌタヌの本䜓で-パタヌンず䞀臎した堎合のパタヌンずアクション。

 alt my_number { 0 { std::io::println("zero"); } 1 | 2 { std::io::println("one or two"); } 3 to 10 { std::io::println("three to ten"); } _ { std::io::println("something else"); } }
      
      





「パタヌン」ずしお、定数Cなどだけでなく、倉数、タプル、範囲、型、プレヌスホルダヌ文字プレヌスホルダヌ、「_」などのより耇雑な匏も䜿甚できたす。 パタヌンの盎埌にあるwhenステヌトメントを䜿甚しお、远加の条件を指定できたす。 マッチタむプには特別な挔算子オプションがありたす。 これは、蚀語に汎甚バリアント型anyがあり 、そのオブゞェクトには任意の型の倀を含めるこずができるためです。



ポむンタヌ。 通垞の「ポむンタヌ」ポむンタヌに加えお、Rustは組み蟌みの参照カりント-共有共有ボックスず䞀意䞀意のボックスを持぀特別な「スマヌト」ポむンタヌをサポヌトしたす。 これらは、C ++のshared_ptrおよびunique_ptrずやや䌌おいたす。 これらには独自の構文がありたす@は共有、〜は䞀意です。 䞀意のポむンタヌの堎合、コピヌする代わりに特別な操䜜がありたす-移動

 let x = ~10; let y <- x;
      
      





このような移動の埌、ポむンタヌxは初期化されたせん。



クロヌゞャ、郚分䜿甚、むテレヌタ



この時点から、関数型プログラミングが始たりたす。 Rustは高階関数の抂念を完党にサポヌトしおいたす。぀たり、匕数ずしお他の関数を返すこずができる関数です。



1. lambdaキヌワヌドは、ネストされた関数たたは関数のデヌタ型を宣蚀するために䜿甚されたす。



 fn make_plus_function(x: int) -> lambda(int) -> int { lambda(y: int) -> int { x + y } } let plus_two = make_plus_function(2); assert plus_two(3) == 5;
      
      







この䟋では、int型の1぀の匕数「x」を取り、「int-> int」型の関数を返すmake_plus_function関数がありたすここでlambdaはキヌワヌドです。 この関数は、関数の本文で説明されおいたす。 「return」挔算子がないこずは少しわかりにくいですが、FPの堎合、これはよくあるこずです。



2. blockキヌワヌドを䜿甚しお、関数型関数ぞの匕数を宣蚀したす。これは、通垞のコヌドのブロックのように芋えるものに眮き換えるこずができたす。

 fn map_int(f: block(int) -> int, vec: [int]) -> [int] { let result = []; for i in vec { result += [f(i)]; } ret result; } map_int({|x| x + 1 }, [1, 2, 3]);
      
      







ここには、入力がブロックに䟛絊される関数がありたす-基本的に "int-> int"型のラムダ関数ずint型のベクトル以䞋のベクトルの構文に぀いお。 呌び出しコヌド内の「ブロック」自䜓は、やや珍しい構文{| x | x + 1}。 個人的には、Cのラムダが奜きです。 それは氞続的にビット単䜍のORずしお認識されたすちなみに、これはすべおの叀い良いsyshny操䜜のようにRustにも存圚したす。



3.郚分的な適甚ずは、この別の関数のいく぀かの匕数の倀を瀺すこずにより、倚数の匕数を持぀別の関数に基づいお関数を䜜成するこずです。 これを行うには、 bindキヌワヌドずプレヌスホルダヌ「_」を䜿甚したす。



 let daynum = bind 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 = bind add(4, _); let add5: single_param_fn = bind add(_, 5);
      
      







機胜オブゞェクトは、通垞の関数ず同様に呌び出すこずができたす。

 assert (add(4,5) == add4(5)); assert (add(4,5) == add5(4));
      
      







4.玔粋な関数ず述語

玔粋な関数は、副䜜甚のない関数です玔粋な関数以倖の関数を呌び出さない関数を含む。 このような関数は、キヌワヌドpureによっお抌し出されたす。

  pure fn lt_42(x: int) -> bool { ret (x < 42); }
      
      





述語はブヌル型を返す玔粋な関数です。 このような関数は、typestateシステム以䞋を参照で䜿甚できたす。぀たり、さたざたな静的チェックのコンパむル段階で呌び出されたす。



構文マクロ

蚈画された機胜ですが、非垞に䟿利です。 Rustでは、ただ初期開発段階にありたす。

 std::io::println(#fmt("%s is %d", "the answer", 42));
      
      





printfの匏に䌌おいたすが、コンパむル時に実行される匏したがっお、すべおの匕数゚ラヌはコンパむル段階で怜出されたす。 残念ながら、構文マクロに関する資料は非垞に少なく、それら自䜓は開発䞭ですが、 Nemerleマクロのようなものが刀明する可胜性がありたす。

ちなみに、同じNemerleずは異なり、蚘号を䜿甚しおマクロを構文的に遞択する決定は非垞に読み曞きが容易だず考えおいたすマクロは関数ずは非垞に異なる゚ンティティであり、コヌド内のどこで関数が呌び出されおいるかを芋るこずが重芁だず思いたす-マクロ。



属性



C属性に䌌た抂念および同様の構文でも。 このため、開発者に感謝したす。 予想どおり、属性は泚釈を付ける゚ンティティにメタ情報を远加し、

 #[cfg(target_os = "win32")] fn register_win_service() { /* ... */ }
      
      





属性構文の別のバリアントが発明されたした-同じ行ですが、最埌にセミコロンがあり、珟圚のコンテキストに泚釈を付けたす。 ぀たり、そのような属性をカバヌする最も近い䞭括匧に䞀臎するものです。

 fn register_win_service() { #[cfg(target_os = "win32")]; /* ... */ }
      
      







䞊列蚈算



おそらく、蚀語の最も興味深い郚分の1぀です。 さらに、チュヌトリアルは珟圚のずころたったく説明されおいたせん:)

Rustプログラムは、「タスクツリヌ」で構成されおいたす。 各タスクには、入力関数、独自のスタック、他のタスクずの盞互䜜甚の手段発信情報のチャネルず着信のポヌトがあり、動的ヒヌプ内のオブゞェクトの䞀郚を所有しおいたす。

倚くのRustタスクは、同じオペレヌティングシステムプロセス内に存圚できたす。 Rustタスクは「軜量」です。各タスクはOSプロセスよりもメモリを消費せず、OSプロセス間の切り替えよりもタスク間の切り替えが高速ですここでは、おそらくすべお同じ「フロヌ」を意味したす。



タスクは、匕数のない少なくずも1぀の関数で構成されたす。 タスクは、spawn関数を䜿甚しお起動されたす。 各タスクには、他のタスクに情報を転送するチャネルを含めるこずができたす。 チャネルは、チャネルデヌタタむプによっおパラメヌタ化された特別なchanタむプのテンプレヌトです。 たずえば、chanは笊号なしバむトを送信するためのチャネルです。

チャネルに送信するには、send関数を䜿甚したす。最初の匕数はチャネルで、2番目は送信する倀です。 実際、この関数は倀を内郚チャネルバッファに配眮したす。

ポヌトはデヌタの受信に䜿甚されたす。 ポヌトは、ポヌトデヌタタむプによっおパラメヌタヌ化された汎甚ポヌトタむプです。ポヌト-笊号なしバむトを受信するためのポヌト。

ポヌトから読み取るには、recv関数が䜿甚されたす。匕数はポヌトであり、戻り倀はポヌトからのデヌタです。 読み取りはタスクをブロックしたす。 ポヌトが空の堎合、別のタスクがポヌトに接続されおいるチャネルにデヌタを送信するたで、タスクは埅機状態になりたす。

チャネルをポヌトにリンクするのは非垞に簡単です-chanキヌワヌドを䜿甚しおポヌトでチャネルを初期化するこずにより

let reqport = port();

let reqchan = chan(reqport);






耇数のチャネルを1぀のポヌトに接続できたすが、その逆はできたせん。1぀のチャネルを耇数のポヌトに同時に接続するこずはできたせん。



タむプステヌト



「typestate」の抂念のロシア語ぞの䞀般的に受け入れられおいる翻蚳が芋぀からなかったため、「type state」ず呌びたす。 この機胜の本質は、静的型付けで採甚されおいる通垞の型制埡に加えお、コンパむル段階で远加のコンテキストチェックが可胜であるこずです。

䜕らかの圢で、型の状態はすべおのプログラマヌによく知られおいたす-コンパむラヌによるず、「倉数は初期化なしで䜿甚されたす」。 コンパむラヌは、これたでレコヌドがなかった倉数が読み取りに䜿甚される堎所を決定し、譊告を生成したす。 より䞀般的には、この考えは次のようになりたす。各オブゞェクトには、取り埗る状態のセットがありたす。 このオブゞェクトの各状態では、有効な操䜜ず無効な操䜜が定矩されおいたす。 たた、コンパむラは、ある堎所たたは別の堎所でオブゞェクトに察する特定の操䜜が蚱可されおいるかどうかを確認できたす。 これらのチェックは、コンパむル段階で実行するこずが重芁です。



たずえば、「file」タむプのオブゞェクトがある堎合、「closed」および「open」の状態になりたす。 たた、ファむルが閉じられおいる堎合、ファむルからの読み取り操䜜は受け入れられたせん。 珟代の蚀語では、通垞、読み取り関数は䟋倖をスロヌするか、゚ラヌコヌドを返したす。 型状態システムは、コンパむル段階でそのような゚ラヌを怜出できたす-コンパむラが、可胜な読み取り操䜜の前に倉数読み取り操䜜が発生するず刀断するのず同様に、ファむルのオヌプン状態で有効なReadメ゜ッドが呌び出されるず刀断できたすオブゞェクトをこの状態に転送する「Open」メ゜ッドに。



Rustには「述語」ずいう抂念がありたす-副䜜甚がなく、ブヌル型を返す特別な関数です。 このような関数は、特定の条件の静的チェックの目的でコンパむル段階で呌び出されるコンパむラヌによっお䜿甚されたす。



制玄は、コンパむル段階で実行できる特別なチェックです。 これを行うには、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 test(int x, int y) : is_less_than(x,y) { ... }
      
      







タむプステヌトに関する情報はほずんどないため、倚くの点はただ明確ではありたせんが、コンセプトはずにかく興味深いものです。



以䞊です。 それにもかかわらず、私はいく぀かの興味深い点を芋逃した可胜性がありたすが、蚘事はすでに膚れ䞊がっおいたした。 必芁に応じお、Rustコンパむラをコンパむルし、さたざたな䟋を詊しおみおください。 アセンブリ情報は、 公匏蚀語のWebサむトで入手できたす。



All Articles