Rust開発チームは、Rustの新しいバージョン1.30.0のリリースをお知らせします。 Rustは、セキュリティ、速度、および並列コード実行を目的としたシステムプログラミング言語です。
rustup
を使用して以前のバージョンのRustがインストールされているrustup
、Rustをバージョン1.30.0にアップグレードするには、次の手順を実行するだけです。
$ rustup update stable
rustup
まだインストールしていない場合は、当社のWebサイトの対応するページからインストールできます。 Rust 1.30.0の詳細なリリースノートは GitHubで入手できます。
安定バージョン1.30.0に含まれるもの
Rust 1.30は、数多くの重要な革新を備えた傑出したリリースです。 しかし、月曜日には、公式ブログに「Rust 2018」の最初のリリースとなるRust 1.31のベータ版を確認するリクエストが発行されます。 これに関する詳細は、以前の出版物「What is Rust 2018」に記載されています。
手続きマクロ
Rust 1.15に戻って、「カスタム派生マクロ」を定義する機能を追加しました。 たとえば、 serde_derive
を使用serde_derive
、次を宣言できます。
#[derive(Serialize, Deserialize, Debug)] struct Pet { name: String, }
そして、 serde_json
を使用してPet
をJSONに変換し、構造にserde_json
ます。 これは、 serde_derive
手続き型マクロを使用したSerialize
およびDeserialize
自動推論のおかげで可能serde_derive
。
Rust 1.30は、他の2つのタイプのマクロを定義する機能を追加することにより、手続き型マクロの機能を拡張します。「属性手続き型マクロ」と「機能手続き型マクロ」です。
属性マクロは、自動出力用の派生マクロに似ていますが、 #[derive]
属性のみのコードを生成する代わりに、ユーザーが独自の新しい属性を作成できるようにします。 これにより、より柔軟になります。派生マクロは構造と列挙に対してのみ機能しますが、属性は関数などの他のオブジェクトに適用できます。 たとえば、属性マクロを使用すると、Webフレームワークを使用するときに次のことができます。
#[route(GET, "/")] fn index() {
この属性#[route]
は、フレームワーク自体で手続き型マクロとして定義されます。 彼の署名は次のようになります。
#[proc_macro_attribute] pub fn route(attr: TokenStream, item: TokenStream) -> TokenStream {
ここに、タイプTokenStream
2つの入力パラメーターがあります。1つ目は、属性自体のコンテンツ用です。つまり、これらはGET, "/"
パラメーターです。 2番目は、属性が適用されるオブジェクトの本体です。 私たちの場合、これはfn index() {}
あり、関数の残りの部分です。
機能マクロは、その使用が関数呼び出しのように見えるマクロを定義します。 たとえば、 sql!
:
let sql = sql!(SELECT * FROM posts WHERE id=1);
このマクロ自体は、SQL式を解析し、構文の正確性をチェックします。 同様のマクロを次のように宣言する必要があります。
#[proc_macro] pub fn sql(input: TokenStream) -> TokenStream {
これは、派生マクロのシグネチャに似ています。角かっこ内にあるトークンを取得し、それらによって生成されたコードを返します。
マクロとuse
useキーワードを使用して、マクロをスコープにインポートできるようになりました 。 たとえば、 serde-json
パッケージのjson
マクロを使用するには、 serde-json
は次のエントリを使用していました。
#[macro_use] extern crate serde_json; let john = json!({ "name": "John Doe", "age": 43, "phones": [ "+44 1234567", "+44 2345678" ] });
そして今、あなたは書く必要があります:
extern crate serde_json; use serde_json::json; let john = json!({ "name": "John Doe", "age": 43, "phones": [ "+44 1234567", "+44 2345678" ] });
ここでは、マクロは他の要素と同様にインポートされるため、 macro_use
アノテーションを使用する必要はありません。
最後に、proc_macroパッケージが安定化され 、手続き型マクロの作成に必要なAPIが提供されます。 また、エラー処理APIが大幅に改善され、 syn
やquote
などのパッケージquote
既にそれを使用しています。 たとえば、以前:
#[derive(Serialize)] struct Demo { ok: String, bad: std::thread::Thread, }
このエラーにつながった:
error[E0277]: the trait bound `std::thread::Thread: _IMPL_SERIALIZE_FOR_Demo::_serde::Serialize` is not satisfied --> src/main.rs:3:10 | 3 | #[derive(Serialize)] | ^^^^^^^^^ the trait `_IMPL_SERIALIZE_FOR_Demo::_serde::Serialize` is not implemented for `std::thread::Thread`
これで発行されます:
error[E0277]: the trait bound `std::thread::Thread: serde::Serialize` is not satisfied --> src/main.rs:7:5 | 7 | bad: std::thread::Thread, | ^^^ the trait `serde::Serialize` is not implemented for `std::thread::Thread`
モジュールシステムの改善
モジュールシステムは、Rustの初心者にとって長い間悩みの種でした。 その規則のいくつかは実際には不便でした。 これらの変更は、モジュールシステムを簡素化するための最初のステップです。
上記のマクロの変更に加えて、 use
には2つの新しい改善点がありuse
。 まず、 外部パッケージがpreludeに追加されるようになりました 。
// let json = ::serde_json::from_str("..."); // let json = serde_json::from_str("...");
難点は、Rustモジュールシステムの機能のために、古いスタイルが必ずしも必要ではなかったことです。
extern crate serde_json; fn main() { // ; , `serde_json` // let json = serde_json::from_str("..."); } mod foo { fn bar() { // ; `foo`, `serde_json` // let json = serde_json::from_str("..."); } // - `use` use serde_json; fn baz() { // - `::serde_json`, // , let json = ::serde_json::from_str("..."); } }
関数をサブモジュールに移動するだけで壊れたコードを取得するのは面倒でした。 これで、パスの最初の部分がチェックされ、 extern crate
対応する場合、モジュール階層内の呼び出しの位置に関係なく使用されます。
最後に、 crateで始まるパスを使用して、現在のスコープへの要素のインポートをサポートするようになりました 。
mod foo { pub fn bar() { // ... } } // use ::foo::bar; // use foo::bar; // use crate::foo::bar;
パスの先頭にあるcrate
キーワードは、パスがパケットのルートから始まることを示します。 以前は、 use
import行に示されたパスは常にパッケージのルートを基準に指定されていましたが、要素を直接参照する残りのコードのパスは現在のモジュールを基準に指定されていたため、パスの動作に一貫性がありませんでした:
mod foo { pub fn bar() { // ... } } mod baz { pub fn qux() { // ::foo::bar(); // , `use`: // foo::bar(); // crate::foo::bar(); } }
新しいスタイルが広く使用されるようになるとすぐに、いプレフィックス::
を使用する必要なく、絶対パスがより明確になることを願っています。
これらのすべての変更により、パスの解決方法の理解が容易になります。 use
ステートメントを除いて、パスa::b::c
が表示されてuse
場合は、次のように尋ねることができます。
- パッケージ名ですか? 次に、その中の
b::c
を探す必要があります。 - キーワード
crate
ですか? 次に、現在のパッケージのルートからb::c
を探す必要があります。 - それ以外の場合は、モジュール階層の現在の位置から
a::b::c
を探す必要があります。
常にパッケージのルートから始まる、 use
のパスの古い動作は引き続き適用可能です。 しかし、一度新しいスタイルに移行すると、これらのルールはどこにでも均一にパスに適用され、コードを移動する際のインポートについて心配する必要が少なくなります。
生の識別子
次の新しい構文を使用して、 キーワードを識別子として使用できるようになりました。
// `for` let r#for = true; // `for` fn r#for() { // ... } // r#for();
これまでのところ、これがあなたにとって有用なケースは多くありません。 しかし、ある日、Rust 2018のプロジェクトでRust 2015のパッケージを使用しようとするか、その逆の場合、キーワードのセットが異なります。 これについては、今後のRust 2018の発表で詳しく説明します。
標準ライブラリのないアプリケーション
Rust 1.6に戻って、標準ライブラリなしでプロジェクトを作成するための「no_std」とlibcoreの安定化を発表しました。 ただし、1つの明確化により、ライブラリのみを作成でき、アプリケーションは作成できませんでした。
Rust 1.30では、 #[panic_handler]
属性を使用して、パニックを個別に実装できます。 つまり、標準ライブラリを使用しないライブラリだけでなく、アプリケーションを作成できるようになりました。
その他
最後に、マクロでは、 vis
修飾子を使用してpub
などのスコープ修飾子をマップできるようになりました。 さらに、 #[rustfmt::skip]
などの「ツール属性」が安定化されました 。 #[allow(clippy::something)]
ような静的分析ツールで使用するには、まだ安定していません。
詳細については、リリースノートを参照してください。
標準ライブラリの安定化
-
Ipv4Addr::{BROADCAST, LOCALHOST, UNSPECIFIED}
-
Ipv6Addr::{BROADCAST, LOCALHOST, UNSPECIFIED}
-
Iterator::find_map
さらに、標準ライブラリには、 trim_left
など、一部のテキストの片側のスペースを削除する機能が長い間ありました。 ただし、RTL言語の場合、ここでの「右」と「左」の意味は混乱を招きます。 したがって、これらの関数の新しい名前を紹介します。
-
trim_left
>trim_start
-
trim_right
>trim_end
-
trim_left_matches
>trim_start_matches
-
trim_right_matches
>trim_end_matches
Rust 1.33では、古い名前を廃止することを宣言する予定です(もちろん、削除はしません)。
詳細については、リリースノートを参照してください。
貨物の強化
このリリースでのCargoの最大の改善点は、進捗バーが追加されたことです!
詳細については、リリースノートを参照してください。
開発者1.30.0
多くの人々が一緒にRust 1.30を作成しました。 皆さん一人一人がいなければ、作業を完了できませんでした。 よろしくお願いします!
翻訳者から:Rustycrateコミュニティのメンバー、および個人的にはvitvakatuとVirtuos86の翻訳と校正の支援に特別な感謝を表明します。