お役立ち情報

プログラミング言語 Rustのメリットやデメリットは?

rust言語のイメージ

プログラミング経験が数年あって、複数のプログラミング言語が扱える方でもRustは最近知った、聞いたことがない、といった方も多いかと思います。Rustはそのくらい新しいプログラミング言語で、IT業界でもそれほど浸透していない言語です。

市場に浸透していないなら学習価値がないのかと思われるかもしれませんが、そうではありません。Rustは将来性のある言語で、今後日本のプロジェクトでも積極的に利用される可能性が高いと言えるでしょう。

理由としては、有名なサービスの一部がRustに書き換えられる事例もあり、特に有名どころとしてはブラウザでおなじみのFirefoxのコンポーネントの一部がRustで作られています。

つまり、Webシステムで使えるということです。使い手の少ない今のうちに習得しておけば、市場価値が上がった際にいち早く仕事を獲得できるでしょう。また仮にRustが伸びなかったとしても学習した内容は他の言語に十分応用が利くため、今後市場がどうなったとしても学習価値は高いです。

■Rustの特徴
Rustの特徴として挙げられているのは、「安全性」「速度」「並行性」です。これらの要素を実現するよう開発されているのですが、さすがにこれだけだと具体性に欠けます。具体的な言語仕様の特徴としては、C++に似ています。

というよりも、C++の問題点を改善する目的からRustは作られています。C++はC言語同様特にメモリ管理が難しいという声が多かったのですが、Rustではその点に力を入れて改良されています。

他にも改良されているポイントは複数あるのですが、C++と大きく異なる点としてはメモリ管理でしょう。

Rustのメリット

上の話の続きになりますが、言語仕様としてはメモリ管理に大きな特徴があります。変数に所有権を与える仕様になっており、複数の変数が同じメモリ領域を確保、もしくは参照している現象が起こらなくなっています。

メモリ領域を意識せずに変数に処理を加えた結果意図しないところで変数を上書きしてしまうようなバグは多々発生しますが、Rustではメモリに所有権があるため、一つの領域に付き一つの変数と決まっています。誤ったコーディングをするとコンパイルエラーになるので、バグに気付きます。

またRustは関数型とオブジェクト指向型の融合を目指している言語であるため、

Rustのデメリット

Rustのデメリットとしては、言語仕様が複雑で難しいということです。製作者はC++の問題点を改良する形でRustを開発しましたが、C++の問題点のなかに難しいというものは入っていなかったようです。

要するにベテランプログラマから見たC++の問題点を解消して開発された言語であるため、プログラミング初心者にとっては難しい独自の概念が複数導入されています。具体的には、「ライフタイム」「オーナーシップ」「静的ディスパッチ」「動的ディスパッチ」などです。

おそらく、他のプログラミング言語の経験があってもRustの扱いには戸惑うかもしれません。ただしRustを学習すれば他のプログラミング言語を見た際にも新たな視点が増えるので、その意味でも学習価値は高いと言えます。

他のデメリットとしては、利用人口が少ないために情報が少ないということです。特に日本ではそこまで普及していないため、環境構築や基本的な書き方はまだしも、バグの解消に戸惑うことなどがあるかもしれません。

ただしアメリカをはじめ海外を含めると利用人口が多くネット上にも情報が出ているため、英語検索すれば問題は解決します。英語が読めない場合も最近はページ丸ごと翻訳する機能がブラウザの拡張機能等で使えるので、問題ないかと思います。

ページをそのまま翻訳すると変な日本語になることが多いのですが、ソースコードがベースであれば不自然な日本語でもだいたい理解できるはずです。

Rustのソースコード例

Rustの特徴やメリット、デメリットは上記の通りですが、具体的なソースコードを見た方がイメージしやすいかと思います。そこで、Rustのサンプルコードを紹介します。ソースコードはイメージを掴む目的なのでなんでも良いのですが、FizzBuzzを例に記述します。

// 関数の引数は`(変数名: 型名, …)`
fn fizzbuzz(n: usize) {
    // `for 変数 in イテレータ {…}`で繰り返し
    // m, m+1, …, (n-1)で繰り返す
    for i in 0..n {
        // `if 条件式 { then式 } else { else式 }`で条件分岐
        // 条件式にはbool型しか書けない
        if i % 15 == 0 {
            println!("FizzBuzz");
        } else if i % 3 == 0 {
            println!("Fizz");
        } else if i % 5 == 0 {
            println!("Buzz");
        } else {
            // `println!`は文字列に`{}`を使うことでフォーマッティング
            println!("{}", i);
        }
    }
}
fn main() {
    fizzbuzz(20);
}

 

引数のある関数設定を行うにはfnと記述します。

for文の記述方法も見ての通り独特です。他のプログラミング言語ではだいたいfor(初期値;終了条件;インクリメント){}といった形になっていますが、Rustではfor 変数 in イテレータ{}という構造になっています。

上のソースコードでは、イテレータで0~nを指定しています。if文の構造は他のプログラミング言語と同じような形ですが、bool方でしか条件指定できません。if文でフラグ判定等のロジックを組むことができないので、その点は不便かもしれません。

また、Rustは配列の使い方も独特です。以下がサンプルコードです。

fn main() {
    let a: [isize;3] = [1, 2 , 3];
    // `&配列` でスライスが作れる。
    let b: &[isize] = &a;
    // スライスをフォーマットするにはプレースホルダが`{:?}`になる。
    println!("{:?}", b); // => [1, 2, 3]
    for elm in b {
    println!("{}", elm);
    }
    // => 1
    // 2
    // 3
    // あるいは`(スライス/配列)[インデックス]`で要素にアクセスできる。
    println!("{:?}", b[0]); // => 1
}

 

配列は要素そのものを格納するスペースで、スライスは参照型のことです。文字列の型はだいたいStringを使用するプログラミング言語が多いですが、Rustの場合Stringだけでなく&strというものがあります。&strは参照型で、Stringに変換することも可能です。具体的には以下のようになります。

fn main() {
    // `&str`を`to_string()`メソッドで`String`に変換
    let mut a: String = "abc".to_string();
    //`String`に`&str`を足すと`String`になる
    // `&str`に`String`を足したり`String`に`String`を足したりはできない。
    a += "def";
    println!("{}", a); // => abcdef
    // `.to_string()`は他の型でも使用できる。
    let x = 1.0.to_string();
    println!("{}", x); // 1
    // `String`を`&str`にするには`as_str()`を使う
    a += x.as_str();
    println!("{}", a); // => abcdef1
}

すぐにRustのソースコードを理解する必要はないかと思いますが、コードに独特な部分が多く、慣れるのに多少時間が掛かる可能性はあります。最初は他の言語との違いが感覚的にわかればそれで良いかと思います。

キャリアカウンセリングのプロとして
あなたに合った案件をご案内します。

まずはお気軽にお問い合わせください!

イメージ