Rustというプログラミング言語をご存知でしょうか。名前くらいは聞いたことがあるかもしれません。

何番煎じか分かりませんが、例に漏れずこの記事もGo言語との比較を行います。

しかし結論から述べてしまうと、RustとGo言語とは比較対象にするようなものではありません。両者の得意領域は異なります。

各々適材適所となる使いどころがあり、一概にどちらがおすすめだと決められる代物ではないです。

RustとGo言語の特徴や機能を理解し、適切に使い分けられるようにしましょう。


Rustとは

Rust(ラスト)はコンパイラ型のプログラミング言語です。公式には2010年に発表されました。

GitHubのオープンソースプロジェクトで開発されています。

ライセンス体系は少々複雑なので、GitHub READMEのLicenseを参照下さい。

ちなみにRustのロゴといえば錆びついた歯車のようなマークが印象的ですが、実は非公式のマスコットキャラにカニがいます。

RustプログラマのことをRustaceanと呼ぶことから、Crustacean(甲殻類)との言葉遊びで作られたキャラクターだそうです。


Rustの特徴

RustはC・C++の仕様に起因する問題点・弱点を解決し、これらの後継言語とするべく開発が進められています。

C・C++の問題点はメモリ管理をプログラマー自身が行わなければならないことでした。

Rustはこの問題点を克服するため、所有権という大きな特徴を持っています。


速度・並行性・安全性

速度面においてRustはC・C++と遜色ないものになりつつあるでしょう。一部の処理ではC++よりも早い結果が出ているくらいです。

また並行・並列プログラミングを安全に実行します。次の項で解説する所有権の仕組みによるものです。

一般的にプログラムで並行・並列処理を実装するのは難しく、一定の経験とスキルが求められます。特にC・C++では難易度が高いです。

これはRustにおいても変わりませんが、言語自体がマルチスレッドでも安全に動作するよう設計されているため実装しやすくなっています。


所有権システム

所有権システムについて正しく理解するにはメモリ・アドレス・ポインタなどの概念に関する知識が必要です。

加えて参照渡し・値渡し・プリミティブ型・オブジェクト型などの変数の扱いに長けていればなお良いでしょう。

その上で馴染みのない方向けに簡略化して説明しますと、ある値を自由に処理できる権利はある変数ただ1つが有しているということです。

具体的なソースコードを提示しましょう。以下の処理を行うとコンパイルエラーになります。

  1. fn main() {
  2. let hello = String::from(“Hello, world!”);
  3. let world = hello;
  4. println!(“{}”, hello);
  5. }

これは所有権がhelloからworldに移ったためです。helloには所有権がないため、”Hello, world!”の文字列を扱うことができません。


Rustのチュートリアル

Rustには公式に翻訳された日本語ドキュメントが存在するため、基本的にはこのサイトを読み進めて理解を深めていきます。

ここではRustを学習するために何をしたら良いかを提示しましょう。


「チュートリアル」はない

「Rust チュートリアル」と検索しても、他言語やWebフレームワークのようなタイトルのチュートリアルサイトを見つけることはできません。

贅沢をいってしまうと日本語の公式ドキュメントの内容には全て目を通しておくべきだと思います。

Rustについて根本から理解するためには、文法やリファレンスだけでなく、概念についても押さえておく必要があるからです。

それでもあえてチュートリアル的な部分を取り出すなら、以下の項目が該当するでしょう。

  • まえがき・導入
  • 1.事始め
  • 2.数当てゲームをプログラムする


学習コストは高め

Rustの学習コストは他の流行りの言語に比べるとかなり高いです。

「導入」にも書かれていますが、Rustのドキュメントは他言語のプログラミング経験者に向けて書かれています。

更に前提知識としてメモリ管理を学ぶ必要があり、これが最もハードルが高いです。

最近はメモリ管理をはじめとするコンピュータの動作を意識しなくてもプログラムが書ける、高水準言語だけを扱う開発者も多いです。

情報系の学部で勉強したり、資格試験のために知識を吸収したことはあっても、プログラムとして動かす経験が充分ではありません。

もちろんRustが管理してくれる仕様にはなっていますが、所有権システムが何をしているのか分からないと途中でつまずくでしょう。


Dockerで試すには

以下のコマンドで簡単に試す環境を構築することができます。この後の記事の閲覧で試したいコマンドが出てきたら活用下さい。

USER=$USER」をセットしないとエラーが発生しますのでお気をつけ下さい。

  1. $ docker pull rust
  2. $ docker run -e USER=$USER –rm -it rust /bin/bash
  3. ~$ apt update
  4. ~$ apt install -y vim tree
  5. ~$ rustc –version
  6. rustc 1.42.0 (b8cedc004 2020-03-09)


Rustのエコシステム

次はRustエコシステムについての紹介です。

Rustのエコシステムでは複数の異なるコマンド機能が、相互に関連を持ちながら1つの大きなシステムを構築しています。

これらのコマンドを利用すると、Rustのディレクトリ構成や生成ファイルの整合性を保ちつつ管理することが可能です。


Cargo

Cargoは依存関係を管理しビルドを行うツールです。プロジェクトの新規作成やコンパイルなどを担います。

例えば「cargo new パッケージ名」は新しいプロジェクトを作成するコマンドです。

  1. ~$ cargo new example
  2. Created binary (application) `example` package
  3. ~$ tree
  4. .
  5. `– example
  6. |– Cargo.toml
  7. `– src
  8. `– main.rs
  9. 2 directories, 2 files

Cargo.toml」はプロジェクトの設定ファイルで、次の内容でテンプレートが作成されます。

  1. [package]
  2. name = “example”
  3. version = “0.1.0”
  4. authors = [“”]
  5. edition = “2018”

プロジェクト名・バージョン・著者・エディションが書かれているでしょう。

ちなみに先述した日本語の公式ドキュメントは2018エディションには非対応のためご注意下さい。

cargo run」でプロジェクトに変更があったかのチェックが行われます。

変更がある場合にのみコンパイルの実行を行う仕組みです。

  1. ~/example$ cargo run
  2. Compiling example v0.1.0 (/root/example)
  3. Finished dev [unoptimized + debuginfo] target(s) in 0.34s
  4. Running `target/debug/example`
  5. Hello, world!


Rustfmt

RustfmtはRuboCop・PHP Formatterなどと同様、コーディングスタイルをチェック・整形するツールです。

設定ファイルからチェック項目の微調整を行うことができます。

Rustfmtを利用するには「rustup component add rustfmt」コマンドで追加インストールを行って下さい。

  1. ~/example$ rustup component add rustfmt
  2. info: downloading component ‘rustfmt’
  3. info: installing component ‘rustfmt’

「src/main.rs」に改行やスペースを加えてから、「rustfmt src/main.rs」コマンドを実行しましょう。整形されている筈です。


Rustup

RustcはRustツールチェーンのインストーラーです。rustc・Cargoなどのツールをアップデートしたり、一覧表示したりします。

「Rustfmt」の項でRustfmtをインストールするのに使用しました。


Rustc

Rustcはコンパイラです。Rustソースコードをライブラリや実行可能なバイナリファイルにコンパイルします。

こちらは「cargo run」と異なりコンパイルのみを行うものです。「rustc ファイルパス」を実行して下さい。

Rustコンパイラを使用してコンパイルすると、プロジェクト直下にmainバイナリファイルが作成されます。

  1. ~/example$ rustc src/main.rs
  2. ~/example$ ./main
  3. Hello, world!


Rustの基本文法

Rustの基本文法のうち特に特徴的なものを、ソースコードを参照しながら説明しましょう。


不変・可変変数

Rustは特に何もしなければ変数を不変変数として扱います。

可変変数にしたい場合は「mut」を付けて宣言して下さい。println()の引数xは4行目で6に変更できる可変変数です。

以下のソースコードからmutを削除するとコンパイルエラーになります。

  1. fn main() {
  2. let mut x = 5;
  3. println!(“X: {}”, x);
  4. x = 6;
  5. println!(“Y: {}”, x);
  6. }


データ型

Rustは静的型付け言語です。変数を宣言するときに型を指定します。

扱うデータ型はスカラー型(整数型・浮動小数点型・数値演算・論理値型・文字型)、複合型(タプル型・配列型)などです。

以下のmain関数の中に宣言を列挙してみました。

  1. fn main() {
  2. // スカラー型
  3. let x: u32 = 3; // 整数型
  4. let y: f32 = 4.0; // 浮動小数点型
  5. let z = 1 + 2; // 数値演算
  6. let b: bool = true; // 論理値型
  7. let str = ‘character’; // 文字型
  8. // 複合型
  9. let tup: (u32, f32) = (3, 4.0); // タプル
  10. let arr = [1, 2, 3, 4, 5]; // 配列型
  11. }


コレクション

Rustのコレクションにはベクタ型・文字列型・ハッシュマップがあります。本項はベクタ型を取り出して紹介するものです。

  1. fn main() {
  2. // ベクタ型
  3. let mut v: Vec<u32> = Vec::new();
  4. v.push(1);
  5. }

ベクタ型は2つ以上の同じ型の値を保持することができるデータ構造です。ベクタ型で宣言した変数のデータはヒープ領域に格納されます。


Go言語とは

Go言語(Go・Golang)もコンパイラ型のプログラミング言語です。2012年にバージョン1.0がリリースされました。

GitHubのオープンソースプロジェクトで、BSDライセンスで管理されています。

マスコットキャラはGopher(ホリネズミ)です。ライセンスがCC BY 3.0という比較的自由度の高いもので、様々なイベントで見かけます。

このライセンスは原著者を明示すれば製品化して販売も可能なもので、技術書・グッズ・技術同人誌などに幅広く利用が可能です。


Go言語の特徴

Go言語の特徴を軽く流していきましょう。


処理速度が速い

Go言語のコンパイルは中間言語を経由せず、直接機械語に変換するものです。このためコンパイル時間が速くリソース消費も少なく済みます。

また処理自体も他の言語に比べ高速です。


並行処理・並列処理

Go言語は言語レベルで並行・並列処理をサポートしています。

複数の処理を同時に行うことが容易なため、更に処理速度は向上するでしょう。


シンプルな記述

Go言語の文法・構文はシンプルです。また表記揺れが少なくなるようになっているので、書きやすく読みやすい状態になります。

これにより学習コストが低く押さえられるのがメリットです。

RustとGo言語の比較

RustとGo言語の比較を行っていきます。


知名度・人気・人口

Go言語はRustと比べると知名度・人気・人口などの点で圧倒的です。これによりライブラリも豊富ですし、情報共有も盛んに行われています。

一方でRustの知名度はまだ低く、Rustの案件は日本にはほとんどありません。

公式ドキュメントやGo言語との比較記事などはかなりありますが、Rust単体で概念まで理解した上で書かれているものは少ないように感じます。


学習コスト

Go言語の学習コストが低いのに対して、Rustの学習コストは高いです。

Rustではまともなものが作れるようになるまで数ヶ月単位の時間がかかるでしょう。

市場価値や今後の開発者人口の推移を考えても、恐らくほとんどの開発者はGo言語を学んだ方が有益な場合が多いと思われます。


処理速度

RustもGo言語も処理速度が速いということをお伝えしました。では両者を比較した場合、どちらが速いのでしょうか。

これはRustの方が速いです。

どちらの言語もWebサービスの高速化によく利用されますが、本当に最速を追い求めたい方はRustに挑戦する意義はあります。


RustとGo言語の使いどころ

先述の通りRustを本当に使いこなしたいと思ったら、それなりの時間とコストをかける覚悟が必要です。

そこまでしても速度に1ミリ秒も妥協したくないという場合はRustを採用すると良いでしょう。

多くの場合はGo言語で事足りる筈です。

ただしRustとGo言語の用途は競合している訳ではありません。

RustはC++の後継として期待されている言語です。Go言語とは畑が違います。

逆に今までC++で行っていた処理をRustに移行する可能性は充分あるでしょう。


おわりに

短い記事ですがなかなか重い内容だったのではないでしょうか。

Rustを採用すると速度的なパフォーマンスが高く、安全性の高いシステムを構築できます。

また学習過程を通してアドレスやポインタの理解も深めることができるでしょう。

これを機にRustを習得してみてはいかがでしょうか。