Rustを0から学んでみた 〜Part.0〜 準備 / 概要 編

Rustの記事シリーズは以下となっています。


[ひとことで言うとこんな記事]

  • Rustにはじめて触れる方が、Rustの特徴を大まかに理解できる
  • 実際に簡単なコードを実行する準備ができる

[こんなひとにおすすめ]

  • Rustの特徴を大まかに理解したいかた
  • 簡単なソースコード実行ぐらいまでを行いたいかた

[目次]

  • Rustのセットアップ方法
  • 実際にネットにあったRustのおすすめ理由

    • 変数寿命を静的に判断し、自動でメモリ解放する点
    • Scala経験者はとっつきやすい言語仕様である点
  • 次回から、TDDBCの課題に挑戦

(※ ネット等から学んだ準備/概要をまとめたものです)

Rustのセットアップ方法

なにはともあれ、実際に触ってみる準備をしていきたいと思います。

インストール(Mac)

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Rust日本語ドキュメント:はじめる

サクッとコンパイル&実行

簡単なRustコードをコンパイルして実行するシェルスクリプト関数。.bashrcとかにでも書いたりしてください。

#!/bin/sh

<< COMMENT

簡単なRustコードをコンパイルして実行する

1. .rsファイルと同じ場所にコンパイル後のファイルを保存
2. コンパイル後のファイルを実行

COMMENT >>

rust(){
  rustc $1 --out-dir `dirname $1` | `echo $1 | sed 's/\.[^\.]*$//'`
}

実行方法

% rust path/sample.rs

実際にネットにあったRustのおすすめ理由

変数寿命を静的に判断し、自動でメモリ解放する点

私にとってめちゃくちゃ新鮮な学びの部分でしたので、ネットの皆様の力をお借りしながら勉強していきます。m(_ _)m

概要

deleteとかunsetとかしなくていいのはガベージコレクション一緒じゃないの?とか思ったんですが、 コンパイル時にすでに、変数のスコープ等でおかしい記述があると怒られる とのことです。

メモリ解放等を自動で判断するために、コードを記述する私達は 所有権 やら 参照と借用 やらなんやらを意識して記述するとのことです。

ここが他の言語と違い、肝となりそうです!

参考:プログラミング言語Rustのススメ

動かしてみる

以下サイトに記載されているサンプルコードを動かしてみました。

参考:Scalaから始めるRust入門 - astamuse Lab

コード

let s1 = String::from("hello");
let s2 = s1; // ここでs1のスコープは終了?

println!("{}, world!", s1); 

実行結果

warning: unused variable: `s2`
 --> sample.rs:4:7
  |
4 |   let s2 = s1; // ここでs1のスコープは終了?
  |       ^^ help: consider prefixing with an underscore: `_s2`
  |
  = note: `#[warn(unused_variables)]` on by default

error[E0382]: borrow of moved value: `s1`
 --> sample.rs:6:26
  |
3 |   let s1 = String::from("hello");
  |       -- move occurs because `s1` has type `std::string::String`, which does not implement the `Copy` trait
4 |   let s2 = s1; // ここでs1のスコープは終了?
  |            -- value moved here
5 | 
6 |   println!("{}, world!", s1); 
  |                          ^^ value borrowed here after move
  • warning : s2が使われていません(warning: unused variable: s2
  • error (borrow of moved value: s1

    • 4行目:s1はで値移動したよ(value moved here)
    • 6行目:値移動したあとに利用してるのはダメだよ(value borrowed here after move)

なんでしょうか、ムダに変数の生存期間を伸ばさずに、メモリをすぐ開放するための機能とでも言えるんですかね??

…引き続き勉強していくこととします。

Scala経験者はとっつきやすい言語仕様である点

参考:プログラミング言語Rustのススメ

参考:Re:FizzBuzzから始めるRust生活

Option型

null safeのやつですね。

let x = Some(2);
match x {
  Some(_) => println!("Someだよ"), // 出力
  None => println!("Noneだよ"),
};

Result型

ScalaだとTry型ですかね。

let number_str = "123456789";  // i8以上の桁数
let result =  number_str.parse::<i8>();
  
match result {
  Ok(n) => println!("success: {}",n),
  Err(e) => println!("error: {}",e),  // 出力
};

// 「error: number too large to fit in target type」

match文

例はこんな感じ。

  • unreachable pattern
  • not covered

をコンパイル時に教えてくれます

let range = 1980 ..= 2020;
  
range.for_each(|num|
  match num {
    year if year % 400 == 0 => println!("{}:うるう年",year),
    year if year % 100 == 0 => println!("{}:うるう年じゃない",year),
    year if year % 4 == 0 => println!("{}:うるう年",year),
    _ => println!("4の倍数関係ない")
  }
);
let range = 1980 ..= 2020;

// タプルもある
range.for_each(|num|
  match (num % 4, num % 100, num % 400) {
    (0,0,0) => println!("{}:うるう年",num),
    (0,0,_) => println!("{}:うるう年じゃない",num),
    (0,_,_) => println!("{}:うるう年",num),
    _ => println!("{}:普通の年",num)
  }
);

Iterator周り

この書き方に慣れたら、結構離れられないですよね。

  • for_each
  • map
  • filter
  • fold

などなど… 

多すぎるので、リンク貼っておきます。

参考:std::iter::Iterator - Rust

次回から、TDDBCの課題に挑戦

私がだいたい新しい言語を学ぶ際に利用させていただいているのが、以下の課題になります。

参考 : TDD Boot Camp(TDDBC) - TDDBC仙台03/課題

順番に課題をこなしていくことで、テスト書きながらリファクタせざるを得ない ような感じの体験ができますので、とても勉強になります。


[これから読んでみたい本]


一緒に様々なことを学んでいく仲間を募集しています。

このサイトのお問い合わせなどからご連絡いただけると幸いです。