Rustのフレッシュルック

私はかなり以前からRustでプログラミングを行ってきましたが、実際にはそれは重要ではありません。 Rustは非常に動的であるため、気が散るのに数か月かかり、実際には異なる言語で書く必要があります。 ただし、変更されていないものが1つあります。開発のベクトルです。 更新ごと、変更ごとに、言語はどんどん良くなっています。



終わりはまだありませんが、今でも言語は数か月前よりも安定しているようで、堅牢なAPI設計パターンがいくつか現れ始めています。 私はこのすべてをより深く探求する時であると思い、私のライブラリをredisに書き換えることに決めました。



ニッチRustはどこですか?



私のほとんどは、Python、C、C ++の3つのプログラミング言語を使用しています。 私は後者と非常に相反する関係にあります。なぜなら、言語のどの部分を使うべきかわからないからです。 Xiは単純なので、簡単です。 一方、C ++には多数の機能が含まれており、その中から使用する機能の多くを選択すると同時に、ほぼ確実に他の誰かが別の機能を選択します。 そして最悪なのは、ホリバーが始まるときです。 私も同様に、STLやブーストへの愛を感じることはありません。ゲーム開発に携わる前からそれは始まりました。 そして、このトピックがポップアップするたびに、間違っていると主張し、言語の本質を理解していない人が少なくとも1人います。



Rustは、Python、C、C ++の使用分野に収まりますが、さまざまなカテゴリでこのニッチを占めています。 Pythonを使用して、小さなユーティリティとスケーラブルなサーバーアプリケーションの両方を記述します。 また、大きなエコシステムがあり、何かが壊れた場合、非常に迅速にデバッグできるため、私に適しています。



Pythonは、他の動的言語とは異なり、1つの興味深い機能を備えています。それは非常に予測しやすい機能です。 たぶん、これは他の言語よりもガベージコレクターへの依存度が低いためです。Pythonは私にとってCPythonと同等であり、CPythonは参照カウントを意味します。 私は、弱いリンクを導入することでループを壊し、クエリの前後にリンクの数のチェックを追加して、ループが形成されないようにする人です。 なんで? 私はそれが好きなので、システムがどのように機能するかを説明できます。 サイクルコレクターをオフにするほどクレイジーではありませんが、すべてを予測可能にしたいのです。



はい、Pythonは低速で、並列コードに大きな問題があり、インタープリターはかなり弱く、動作が異なるように見える場合もありますが、実際には大きな問題は発生しません。 何かを始めて、1か月間、帰って、戻ることができます。それでも動作します。



Rustは、CおよびC ++と非常によく似たメモリとデータで動作するようになっています。 しかし、これらの2つの言語とは異なり、型推論と、プログラマーのすべてのニーズを満たす適切に作成された標準ライブラリにより、APIプログラミングの点でPythonにはるかに似ています。



壁にぶつかる



面白いことに、最初は、Rustでのプログラミングが壁に絶えずぶつかっているように見えます。 はい、これはPythonではありません。また、これに馴染みのあるものの多くはRustでは機能しません。 これは同時にC ++ではないため、 依存関係のチェックが最大の敵になります。 結局、これはうまくいくはずです。だから、この馬鹿げたものは、彼が私よりも良いことを知っていると思い、これを行うことを禁じていますか?



真実は、借用チェッカーが完全ではないということです。 それは危険から保護しますが、時々それを禁止しすぎます。 私の経験に基づいて、彼は実際にあなたが予想するよりもずっと間違っていると言うことができます。 少し違った考え方を始める必要があります。 そして最も重要なことは、修正するのが最も難しい、最も危険な設計エラーを防ぐことです。 PythonはGILを使用してスレッドを操作しますが、言語自体が登場して以来、GILは本当に必要とされてきました。 インタプリタは、何も修正することがほとんど不可能なように書かれています。



試してみると、Rustで並列化するタイミングを決定するときに間違いを犯す可能性がありますが、実際にこれを行う必要があります。 言語はあなたにもっと考えさせます、そしてそれは良いと思います。 「OOPは10億ドルの間違いです」という論文を説教するのに屈したくはありませんが、人々が書くコードはほとんどプログラミング言語に依存していると思います。 C ++、Java、Pythonではシンプルであるため、客観的に記述します。 ええ、鳥は「動物」クラスのオブジェクトになります。 そのような楽器を選択すると、少し違った考え方を始めますが、それは良いことです。 CPU容量はそれほど速く成長しておらず、単位時間あたり1つのオブジェクトのみを考慮することはすでに無意味です。 コレクションと必要な変換について詳しく説明する必要があります。



錆が刺激する



Rustでのプログラミングは私に喜びをもたらします。 はい、私はまだ言語が私にさせるすべてに同意することはできませんが、私は長い間プログラミングからそれほど多くの喜びを受け取っていないと言うことができます。 この言語は、問題を解決するための多くの新しいアイデアを私に与えてくれ、安定したリリースを待つことができません。



さびは多くの理由で刺激を受けています。 そして、主なものは実用的です。 Haskellでの経験があり、Erlangを試しましたが、実用的な言語のように見えるものはありません。 多くのプログラマーが彼らを崇拝していることは知っていますが、これらの言語は明らかに私には向いていません。



さびは、誰もが試すことができるものの1つであり、楽しいものになります。 まず(コンパイラのバグに遭遇するまで)、クラッシュしません。 そして、コンパイルエラーに対して素晴らしいメッセージを生成します。 また、依存関係の追跡機能を備えたパッケージマネージャーも備えているため、不潔なまたは存在しないエコシステムにつまずくことを恐れることなく、他の人のライブラリの使用を開始できます。 Pythonでのパッケージの操作は、ここ数年でかなり進化しましたが、それでも最も残念な部分の1つです。 RustのバッチマネージャーであるCargoは生後6か月しか経っていませんが、定期的なメンテナーがおり、使用するのが楽しいです。



最高品質のインストーラーですら。 コンパイラ、ドキュメントユーティリティ、およびパッケージマネージャを提供します。 そして、プログラミングの喜びへの大きな貢献は、ドキュメントを操作するためのツールによってもたらされ、すぐに使用できる優れたヘルプを作成します。 javadocよりもSphinxに少し似ているようにしたいのですが、将来的には非常に良いデポジットです。



しかし、Rustで最も興味深いのはささいなことです。 私がそれをいじり始めたとき、FFIの優れたサポートに感銘を受けました。ライブラリライブラリから何かを呼び出すことができるという事実に加えて、コンパイラはそれらを見つけてリンクします。 そして、そのようなことは、言葉では言い表せないほど多くの言語に隠されています。 include_str!



マクロがありinclude_str!



コンパイル時にファイルをバイナリの文字列に読み取ります、すごい! また、たとえば環境変数を実行可能ファイルにドラッグすることもできます。



APIデザイン



Rustを使用する最も興味深い部分は、APIを正確かつ美しく作成する方法を見つけることです。 言語としての錆は、この観点から間違いなく他の多くのものよりも複雑です:プログラマーとして、あなたは簡単に(システムプログラミング言語のように)書くことと(Pythonのように)美しい高レベルのインターフェースを提供することの間で引き裂かれます。



また、言語自体がそのようなアプローチを促すため、美しいAPIを作成する傾向があります。 一方で、この言語は非常に表現力があり、他方で、信じられないほどの可能性を提供します。



これらの「グッズ」の1つは、非常にクールなタイプのシステムです。 言語は静的に型付けされていますが、型推論メカニズムにより、本当に美しいコードを書くことができます。 たとえば、Redisの私のドライバーでは、次のように記述できます。



 extern create redis; fn main() { let client = redis::Client::open("redis://127.0.0.1/").unwrap(); let con = client.get_connection().unwrap(); let (k1, k2) : (i32, i32) = redis::pipe() .cmd("SET").arg("key_1").arg(42i).ignore() .cmd("SET").arg("key_2").arg(43i).ignore() .cmd("GET").arg("key_1") .cmd("GET").arg("key_2").query(&con).unwrap(); println!("result = {}", k1 + k2); }
      
      





比較のために、Pythonコード:



 import redis def main(): client = redis.Redis('127.0.0.1', 6379) pipe = client.pipeline() rv = pipe \ .set("key_1", 42) \ .set("key_2", 43) \ .get("key_1") \ .get("key_2").execute() k1 = int(rv[2]) k2 = int(rv[3]) print 'result = {}'.format(k1 + k2) if __name__ == '__main__': main()
      
      





興味深いことに、Rustライブラリのサイズと「純度」はPythonライブラリに似ていますが、はるかに低いレベルです。 Pythonライブラリーは各呼び出しに個別のメソッドを提供します。Rustのバージョンは(若いため)低レベルAPIのラッパーであり、リクエストは各引数の呼び出しのシーケンスとして手動で作成する必要があります。 それでも、ユーザーの最終結果は同じように見えます。 さらに、Rustにはもう少しエラーハンドラーが必要です(ただし、アプリケーションを終了させるunwrap



を使用してこれを回避しましたが、Pythonバージョンでも同じことが起こり、エラーチェックもスキップしました)。



Rustのバージョンを支持する大きなプラスは、タイプセーフです。 そして、これは合計で型が言及されている場所が2つしかないという事実にもかかわらず、これらはPythonでも全体へのキャストが使用されたのと同じ場所です。



しかし、これはRustでできる最善の方法ではありません。可能性を広げるコンパイラ拡張機能があります。 たとえば、Postgres SQLコマンドの正確性をチェックするライブラリrust-postgres-macrosがあります



 test.rs:8:26: 8:63 error: Invalid syntax at position 10: syntax error at or near "FORM" test.rs:8 let bad_query = sql!("SELECT * FORM users WEHRE name = $1"); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: aborting due to previous error
      
      





これは本当にエキサイティングです。



PSチャンネルのrust-apidesignでMozilla IRCネットワークのRust API設計について話すことができます。



未来



Rustのメモリ管理コンセプトは、プログラミングモデルとして受け入れられるほど強力ですか? よくわかりません。 しかし、舌はすでに立ち上がっていると信じています。 そして、借用チェッカーが不要であると人々が判断したとしても、これがこの言語の普及を妨げないように思えます。 Rustは素晴らしいことを約束し、ガベージコレクターなしでも素晴らしい動作をします。



これは並外れたオープンソースプロジェクトです。 そして彼はもっと助けが必要です。 Windowsサポートはどんどん良くなっていますが、それでも多くの作業が必要です。



All Articles