今始めずにいつやるの? Rust の始め方

f:id:Naotsugu:20190414011634p:plain

Rust の文法以前、環境構築と使い方を簡単に。


Rust

  • 比較的若く近代的な言語仕様(2006~)
  • マルチパラダイム
  • 静的型付
  • 型推論あり
  • null がない
  • ジェネリクスはある
  • C++ のスマートポインタを発展させたメモリ安全
    • 安全な並列性
    • 所有権・借用・ライフタイムによる GC 不要なメモリ管理
    • この概念により学習難易度は高い
  • Firefox のレイアウトエンジン Servo が Rust 製
  • 自転車の車輪がモチーフのロゴが・・ダサい


Rust のインストール

rustup というRust のツールチェーン管理ツールを利用することが推奨されています。

rustup を利用することで Rust のバージョンと関連するツールが簡単に管理できるようになります。


rustup のインストール

rustup のインストールは以下で完了です。

$ curl https://sh.rustup.rs -sSf | sh

インストールオプションの選択が求められるので 1) Proceed with installation (default) を選択します。

Windows の場合は rustup-init.exe をダウンロードして実行します。


インストール完了すると、~/.cargo/binrustc, cargo, rustupといったツールが配備されます。

合わせて環境変数~/.cargo/bin へのパスが追加されます(すぐに Rust を始めるにはターミナルを立ち上げ直すか source コマンドで環境変数を読み込みます)。

.profile などに export PATH="$HOME/.cargo/bin:$PATH" が追加されているはずです。


バージョンの確認

インストールが完了したら以下でバージョン確認ができます。

$ rustc --version
rustc 1.34.0 (91856ed52 2019-04-10)


cargo は Rust のビルドツールです。cargo のバージョンも見ておきましょう。

$ cargo --version
cargo 1.34.0 (6789d8a0a 2019-04-01)


アップデート

Rust は 6週間毎のリリースサイクルがあります。関連ツールをアップデートするには以下のようにします。

$ rustup update


アンインストール

アンインストールは以下で可能です。

$ rustup self uninstall


Hello World

通常 Rust でプログラムを書く場合は cargo を使います。

しかし、ここでは cargo を使わず、Rust のコンパイラで直接 Hello World してみましょう。

$ mkdir hello_world
$ cd hello_world
$ touch main.rs


main.rs を以下のように編集します。

fn main() {
    println!("Hello, world!");
}


コンパイルrustc を使います。

$ rustc main.rs


作成された main を実行してみましょう。

$ ./main
Hello, world!


Hello Cargo

Rust には cargo というビルドツール(パッケージマネージャ)がついてきます。


cargo でプロジェクトを作成してみましょう。

$ cargo new hello_cargo --bin
     Created binary (application) `hello_cargo` package

—bin で実行バイナリを生成するプロジェクトを作成します。-lib とするとライブラリ用のプロジェクトになります。


プロジェクトは以下のように作成されます(tree がなければ brew install tree でインストールできます)。

$ tree -a hello_cargo/
hello_cargo/
├── .git
│   ├── 省略
├── .gitignore
├── Cargo.toml
└── src
    └── main.rs

git 管理のプロジェクトが自動的に作成されます。


Cargo.toml は以下のようになっています。

[package]
name = "hello_cargo"
version = "0.1.0"
authors = ["naotsugu"]
edition = "2018"

[dependencies]

golangdep で使う Gopkg.toml と同じく TOML 形式で設定を記載します。

Java で言えば build.gradle ですね。


main.rs は以下のようになっています。

fn main() {
    println!("Hello, world!");
}


ビルド

ビルドは cargo build をするだけです。

$ cd hello_cargo

$ cargo build
   Compiling hello_cargo v0.1.0 (/.../hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 1.30s


実行

target/debug に実行ファイルができるので実行できます。

$ ./target/debug/hello_cargo
Hello, world!


cargo run とするとコンパイルと実行を同時に行います。

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.10s
     Running `target/debug/hello_cargo`
Hello, world!

出力を見ると分かる通り、ソースに変更がなければコンパイルは行われません。


check

開発時にはコンパイルが通るかどうかを調べるために cargo check を使うことができます。

$ cargo check
    Checking hello_cargo v0.1.0 (/.../hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.61s

cargo build より早くコンパイル可能かどうかをチェックできます。


リリースビルド

リリースモジュールのビルドは —release を使います。

$ cargo build --release
   Compiling hello_cargo v0.1.0 (/.../hello_cargo)
    Finished release [optimized] target(s) in 0.85s

最適化された実行モジュールが ./target/release/hello_cargo に出力されます。


クレート

Rust ではライブラリ(またはパッケージ) を クレート(crate) と呼びます。

Java での Maven リポジトリであったり、npm リポジトリに相当するのが crates.io になります。

f:id:Naotsugu:20190413172418p:plain


cargo で crates.io からクレートを探すことができます。

Rust の日時を扱うクレート chrono を検索してみましょう。

$ cargo search chrono
chrono = "0.4.6"                    # Date and time library for Rust
chrono-tz = "0.5.1"                 # TimeZone implementations for rust-chrono from the IANA database
...


依存の追加

Cargo.toml に依存を追加してみましょう。先程検索した chrono[dependencies] セクションに追加します。

[package]
name = "hello_cargo"
version = "0.1.0"
authors = ["naotsugu"]
edition = "2018"

[dependencies]
chrono = "0.4"


クレートのバージョンはセマンティック バージョニング(SemVer)になっています。

"0.4" とするとバージョンは >=0.4.0 <0.5.0 の範囲のバージョンが採用されます。

0.4.6(^0.4.6 の省略形)とすると、>=0.4.6 <0.5.0の範囲内のバージョンが採用されます。

初回ダウンロードしたバージョンは、プロジェクトフォルダにあるCargo.lock に反映され、次回以降は同バージョンが利用されます。cargo update を実行すれば、公開されているクレートの新しいバージョンが反映されます。


追加したクレートを使ってみましょう。

use chrono::Local;

fn main() {
    println!("Hello, world! {}", Local::today());
}

Local::today() で今日が取得できます。


実行してみましょう。

$ cargo run
    Updating crates.io index
  Downloaded chrono v0.4.6
  Downloaded time v0.1.42
  Downloaded num-integer v0.1.39
  Downloaded libc v0.2.51
  Downloaded num-traits v0.2.6
   Compiling num-traits v0.2.6
   ...
    Finished dev [unoptimized + debuginfo] target(s) in 9.47s
     Running `target/debug/hello_cargo`
Hello, world! 2019-04-13+09:00

クレートの依存が解決されて実行できました。


ドキュメント

cargo doc —open でドキュメントを照会できます。

$ cargo doc --open
    Checking libc v0.2.51
 Documenting libc v0.2.51
    Checking num-traits v0.2.6
 Documenting num-traits v0.2.6
    Checking time v0.1.42
    Checking num-integer v0.1.39
    Checking chrono v0.4.6
 Documenting num-integer v0.1.39
 Documenting time v0.1.42
 Documenting chrono v0.4.6
 Documenting hello_cargo v0.1.0 (/.../hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 7.65s
     Opening /.../hello_cargo/target/doc/hello_cargo/index.html

依存ドキュメントがダウンロードされ、デフォルトブラウザが立ち上がります。

f:id:Naotsugu:20190413172336p:plain

先程追加した chrono のAPIなどを確認することができます。

ドキュメントはソースに記載された/// で始まるものを対象に生成され、コメント中には Markdown 記法で記載できます。


Rust plugin for IDEA

プラグインのインストール

f:id:Naotsugu:20190413173808p:plain


再起動してRustプロジェクト作成

f:id:Naotsugu:20190413174236p:plain

プロジェクト名入力

f:id:Naotsugu:20190413174302p:plain

補完やジャンプなど一通りできます。

f:id:Naotsugu:20190413174319p:plain



プログラミングRust

プログラミングRust