Rustに導入される予定の新しいエディション、Rust 2018について、リリース前に得られる情報をご紹介します。
Rust 2018とは何か
Rust公式ブログの [What is Rust 2018?] (https://blog.rust-lang.org/2018/07/27/what-is-rust-2018.html)より、大雑把に要約してみます。
Rust 2018とは、簡単に言えばC++におけるC++11みたいなものです。これまでのRustはRust 2015と呼ばれることになり、Rust 2018ではRust 2015からの破壊的変更が含まれます。12/6にリリース予定のRust 1.31が、Rust 2018の最初のリリースとなる予定です。Cargo.toml
内でエディションを指定することにより、Rust 2018の機能が利用できるようになります。
Rust 2015との互換性
Rust 2018のリリース後も、RustコンパイラはRust 2015で書かれたコードをコンパイルできます。また、Rust 2018からRust 2015で書かれたライブラリを使うことも、その逆も可能です。コンパイラは異なるエディションのコードをリンクすることができます。また、Rust 2015から2018へと自動変換するためのツールcargo fix
が提供される予定です。
Rust 2018リリース後の開発について
Rust 2018のリリースというのは、あくまで最初のリリースであるに過ぎません。Rust 2018がリリースされた後でも、Rust 2018への機能の追加は続けて行われます。また、必要であればRust 2015にも変更が加えられます。
なぜエディションという形をとるのか
ユーザのコードを破壊することなく、破壊的変更を取り入れることのできる方法だからです。
また、Rustでは6週間ごとのリリースで細かい変更を積み重ねてきましたが、これはRustの変化を追い続けることを難しくしています。エディションという密なパッケージにすることで、これまで行われた変更を大きな視点から知ることができます。
Rust 2018での変更点
The Rust Edition Guideを読めば、今の所予定されている変更点を伺い知ることができます。いくつか以下に紹介しますが、この文書自体が書きかけで、確定ではありません。
追記(2018/11/30)
The Rust Edition Guideがかなり整備され、どの機能がどのバージョンのrustcから導入されるかわかるようになりました。また、async,await構文はRust 1.31時点では導入されず、安定化はRust 2018リリースより後となりました。
追記(2019/11/9)
Rust 1.39にて、async,await構文がstableになりました。
非同期処理
async、await構文が追加されます。
モジュール
extern crate
が不要になり、use
文で他クレートのシンボルを直接インポートできるようになります。
パス指定がクレート名で始まった場合、絶対パスとして認識されます。つまり、次のような書き方が可能になります。
mod foo {
fn bar() {
let a = std::boxed::Box::new(1);
}
}
Rust 2015では相対パスのため、foo
の中のstd
という名前のモジュールを探してしまいますが、Rust 2018では期待通りにstd
クレート内のパスをたどってくれるようになります。パスがcrate
で始まった場合、現在のクレートの先頭からのパス指定となります。同様に、self
は現在のモジュール、super
は親モジュールからのパス指定となります。
pub(crate)
がcrate
に変更され、短く書けるようになります。
マクロがuse
文でインポートできるようになるなど、Rustの他のシンボルと同様にモジュールベースで扱えるようになります。
ライフタイム
いくつかの省略した書き方が導入されます。
例えば、fn
やimpl
宣言において、<>
内でのライフタイムの宣言が省略できるようになります。
また、Non-lexical lifetime(NLL)が導入されます。Rust 2015では、スコープ範囲をベースにライフタイムを管理していましたが、NLLによりスコープに縛られないもっと柔軟な書き方が可能になります。
トレイト
impl Trait
構文とdyn Trait
構文が導入されます。Rust 2018では、トレイトオブジェクトを使う時は、dyn Trait
構文が推奨されます。つまり、&Trait
よりも&dyn Trait
を使うことになります。これらの構文はRust 2015にもすでに導入されています。
Rust 2018を試す
Nightlyコンパイラで、#![feature(rust_2018_preview)]
を追加します。
#![feature(rust_2018_preview)]
fn main() {
}
mod a {
pub fn foo() {
let _ = std::boxed::Box::new(1); // 新しいパス指定方法
}
}
Cargoを使う場合は、以下をCargo.toml
に追記します。こちらもNightlyが必要です。main.rs
へのfeatureの指定は不要のようです。
cargo-features = ["edition"]
[package]
edition = '2018'
ただし、以上の指定をしても、予定されている機能が全て有効になるわけではないようです。例えば、NLLを有効にするためには#![feature(nll)]
の追加が必要です。
Rust 2018がリリースされた後でも、これまでのRust(Rust 2015)で書かれたコードは引き続き使えるようですので、とりあえずひと安心というところでしょうか。Rust 2018で起こる変更は確定ではなく、issueやフォーラムで活発な議論が行われている最中です。