RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

【Rust入門】魅力とはじめ方

Rust入門

こんにちは高照です。
今回はここ数年で急成長を遂げたRustというプログラミング言語を勉強しましたので記事にしました。
本記事ではRustについての解説プログラミングのはじめ方基本的なプログラムの記法をまとめます。

Rustとは

RustはMozilla社が支援するオープンソースプログラミング言語です。
また、2016〜2019年でStack Overflow Developer Surveyで「最も愛されているプログラミング言語」で一位を獲得し続けていた言語で初めにも記述したように急成長を遂げました。しかしながら、学習難易度が高い言語とも言われていて今後の学習のしやすさが課題となってきます。

Rustの魅力

Rustの魅力的なポイントとして以下の6つを上げることができます。

  1. 実行速度の速さ
  2. モダンな文法
  3. OSからWebアプリケーションまでカバー
  4. ツール群の充実性
  5. 強力な安全性
  6. エディションによって互換性を担保

これらの魅力を少し解説していこうと思います。

1. 実行速度の速さ

Rustはプログラムの実行速度を重視した言語で、競技プログラミングでも使用されているC言語にも匹敵する実行速度を出すことができます。
この理由として以下のような要因が考えられます。

機械語コンパイルされる
JavaPythonなどは、独自の仮想マシン上でコードを実行することで様々なプラットフォームでもコードを実行することができるようになるという利点があります。一方、実行には仮想マシンを介す必要があるため速度においては不利と言えます。
Rustは仮想マシンを使用せず直接機械語コンパイルできるためこれらの問題での速度低下は起きません。

ガベージコレクションを持たない
自動で使用したメモリを開放する機能であるガベージコレクションを持ちません。
そして、C言語C++では手動でメモリ管理をする必要もありません。
Rustは所有権借用ライフタイムというこれまでにない仕組みでメモリを管理されます。 そのためガベージコレクションや手動のメモリ解放に頼らないため速度と安全性を兼ね備えています。

ゼロコスト抽象化の追求
Javaのabstractのような共通部分を抜き出す固有の処理は、抽象化する処理をRustではコストを払うことなく使用することができます。この抽象化は大規模なプロジェクトを作成するにあたり多様されるため、ゼロコストで抽象化をすることができるというのは処理速度面で大きなアドバンテージだと言えます。

2. モダンな文法

Rustは多くのプログラミング言語を参考にし、設計されました。
Rustはデフォルトで変数割当は不変となっています。つまり、変数を作成した後に、値を再代入しようとするとコンパイルエラーとなります。例は以下の通りです。

fn main( ) {
    // 変数aを宣言し1で初期化する
    let a = 1;
    // aに2を再代入しようとするとコンパイルエラー
    a = 2;
}

また、letの後ろにmutをつけることで再代入可能な変数を扱うことができます。

fn main( ) {
    // 変数aを宣言し1で初期化する
    let mut a = 1;
    // aに2を再代入する
    a = 2;
}

変数をデフォルトで不変にするメリットは、長いスコープ内で代入を繰り返してしまい、値がどう変化してしまうか把握できなくなってしまうことを防ぐことができます。
また予期しない変数への再代入などにより、バグが発生しづらいコーディングをすることができます。

これ以外にもモダンな文法が含まれていますが、現段階で説明してしまうと非常に難しくなってしまうため割愛いたします。

3. OSからWebアプリケーションまでカバー

Rustはシステムプログラムだけでなく、Webアプリケーションのバックエンド開発を行うことも可能です。
activex-webというフレームワークが存在し、Node.jsなどのフレームワークと遜色ない開発が可能です。

4. ツール群の充実性

RustにはCargoというパッケージマネージャ・ビルドツールが存在します。
Cargoはライブラリのインストールやプログラムのビルドを全て行うことができます。
今回、使用するのは以下の3つのコマンドです。

また、プログラミングする際に使用するエディタも充実しています。
IntelliJやCLion、Visual Studio CodeVimEmacsなど多くのエディタでプラグインが作成されています。
今回、私はVisual Studio Codeを使用しコーディングしていきます。

5. 強力な安全性

Rustはメモリ安全ではない操作スレッド安全ではない操作を未然に防ぐように設計されています。

  • メモリ安全ではない操作
    メモリを手動で管理するC言語C++などでは「メモリの開放を忘れてしまう」ことや、「開放したはずのメモリをもう一度開放しようとしてしまう」などの状況をメモリ安全ではないと言います。
    ガベージコレクションを持たない」の項目でも説明したとおり、Rustでは手動管理ではなく所有権借用ライフタイムでメモリ管理されることでメモリの安全を保証しています。

  • スレッド安全ではない操作
    2つの並行するスレッドがあると仮定し、それぞれa = 1,b = 2の処理を非同期に行うとします。
    a = 1の処理が終わった際にbの値はどうなっているのでしょうか。
    答えは分かりません
    なぜかというと、a = 1の処理が終了した際に b = 2の処理がまだ終了していない場合も考えられるからです。この状態をスレッド安全ではないと言います。
    Rustはこの状態をプログラム上で考慮されているかを厳しくチェックし、スレッド安全であることを保証します。

6. エディションによって互換性を担保

Rustには2015エディションと2018エディションが存在し、相互の互換性が効かない文法が存在します。
しかし、ライブラリ単位ごとならば異なるエディションであっても問題なく使用することができます。

環境構築

では、実際に環境構築しプログラムを作成していきましょう。
今回はWindows環境にRustをビルドできる環境を作成していきます。
まずは、以下のリンクからRustをダウンロードしインストールします。

www.rust-lang.org

OSが32Bitか64Bitを確認しダウンロードしてください。

RustDLページ

ダウンロードしたrustup-init.exeを起動しインストールを開始します。
起動するとコマンドプロンプトが立ち上がり処理を続けるかを聞かれるためyと入力しEnterを押下します。

RustInstall確認

その後、インストール方法を聞かれますので、デフォルトの1と入力しEnterを押下します。

RustInstall項目

以下のように出力されれば、Rustのインストールは完了です。

RustInstall完了

続いてVisual C++ビルドツールのインストールを行います。
以下より、Build Tools for Visual Studio 2019をダウンロードし実行してください。

visualstudio.microsoft.com

インストールする項目でC++ Build Toolsをチェックし、右下のインストールボタンを押下します。

VS Build Tools 2019 Install

お疲れさまでした。
以上でRustの開発環境が整いました。
次節からプロジェクトを作成し、コードを書いてみましょう。

プロジェクトの作成とHello, World!

まずはプロジェクトを作成します。
わかり易い場所に作業用のフォルダを作成してください。
その後、コマンドプロンプトにて以下の例の様に、cdコマンドを使用し作成したフォルダへ移動してください。

) cd Desktop¥Rust¥Project  

移動後、先程説明にも出てきたcargoを以下のように使用します。

cargo new test_rust

コマンドを実行後、フォルダ内にtest_rustフォルダが作成されます。
ではそのまま実行してみましょう。

cd test_rust
cargo run

実際に実行すると、以下のような結果となりHello, World!と表示されます。

Rust実行
Rustではプロジェクトを作成した段階でHello,World!をすることができます。
ではコードの中身を見ていきましょう。

メインコードはtest_rust¥src¥main.rsに記述されています。
中身は以下のようになっています。

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

main関数が記述され、関数内でprintln!メソッドが呼ばれ、その中身が表示されていることが分かります。
ではもう少し本格的にプログラムを作成して見ましょう。

コーディング

まずは簡単なRustのプログラムから作成しながら見ていきましょう。

以下プログラムではvalという変数を宣言し、数字の1234を格納及び、表示しています。
Rustは型推論により自動で変数の型を決めてくれます。
今回は自動で32bitのint型で宣言されますが、明示的に変数の後ろに:i32と記述することも可能です。

println!内の"{}"にはそれ以降の引数の値が置き換えられ表示されます。

fn main() {
    let val = 1234;
    println!("{}", val);
}
fn main() {
    // 明示的に型の指定もできる
    let val:i32 = 1234;
    println!("{}", val);
}

また変数のデータ型以下のようになっています。

説明
i8 8bit 符号あり 整数
i16 16bit 符号あり 整数
i32 32bit 符号あり 整数
i64 64bit 符号あり 整数
u8 8bit 符号なし 整数
u16 16bit 符号なし 整数
u32 32bit 符号なし 整数
u64 64bit 符号なし 整数
f32 32bit 浮動少数点数
f64 64bit 浮動少数点数
bool 論理値
char 文字型

当たり前ではありますが、他の言語でもあるものは全て揃っています。

また、他にも文字列型や配列、タプルなども存在します。

では最後にfor文とif文の使用方法を見てみましょう。
以下プログラムは、1~9で偶数の値を表示するプログラムです。

  • for文:1~9の値を順にxに代入しループします。
  • if文:xを2で割ったあまりが0かどうかを判定することで偶数であるかを判定し画面表示しています。
fn main() {
    for x in 1..10 {
        if x % 2 == 0 {
            print!("{} ", x);
        }
    }
    println!();
}

最後に

一般でも言われている通り、Rustは学習するには難しい言語だと感じましたが、それ以上に魅力もあることを知っていただけましたでしょうか。
また、私の印象としては、処理が高速なC言語C++寄りでプログラムのモダンな記法はPythonやSwiftに似ていると思いました。また、Rustを学ぶ上でC言語のポインタという概念を学習しておくと、理解しやすいのかなと感じました。ポインタはC言語の関門とも言われているため、Rustは難しい言語と言われているのでは無いかと思います。(ポインタを理解すると、Rustは割りかしすんなりと理解できるかもしれません。)
今回はあまり突っ込んだプログラムの解説はできませんでしたが、また機会があれば続きを書きたいと思います。

※冒頭画像のRustロゴは、公式サイトで配布されているものを使用しております。
 また、このロゴはRust財団によってCC-BYの下で配布されています。


◆TECH PLAY
techplay.jp

◆connpass
rakus.connpass.com

Copyright © RAKUS Co., Ltd. All rights reserved.