tkt989 🍵 ブログ

日々のメモ

Rust入門 2 基本的な文法

2018/08/04

本当は数当てゲームなどを作る章が続いているのですが、順番が前後させて文法を先に学んでおきます。

変数

変数の宣言は以下のようにする。

let num = 10;

型を示すこともできる。

let num: i32 = 100;

Rustでは変数はデフォルトでイミュータブルになっていて、書き換えることはできない。

let x = 5;
x = 10; // コンパイルエラー

ミュータブルにしたいときはmutを付ける

let mut x = 5;
x = 10;

また、未初期化の変数を宣言することはできるが、使用しようとするとコンパイルエラーになる。

let x: i32;

println!("{}", x); // コンパイルエラー

プリミティブ型

  • bool

おなじみの真偽値。true or false

let changed: bool = true;
  • char

文字を表す。ユニコードに対応している。

let ch: char = 'a';
let poop: char = '💩';
  • i8
  • i16
  • i32
  • i64

符号あり整数型。数値はビット数を表す。

let x: i32 = 1234;
let y: i16 = -100;
  • u8
  • u16
  • u32
  • u64

符号なし整数型。こちらも数値はビット数を表す。

let x: u32 = 1234;
let y: u16 = -100; // コンパイルエラー
  • isize
  • usize

実行環境のポインタサイズで変わる型。32bitではi32 or u32、64bitではi64 or u64になるということかな。

  • f32
  • f64

浮動小数点数型。数値は単精度か倍精度かを表す。

let pi: f32 = 3.1415926535;
  • 配列

おなじみの配列。要素の型はすべて同じにしないといけない。

let a: [i32; 3] = [1, 2, 3];
let x = a[0] + a[1]; // x = 3
  • タプル

固定サイズのリスト。要素の型は異なっても良い。

let t: (i32, f32) = (3 0.141592);
let x = t.0 + 3;

t.0のようにタプルのインデックスを指定することで要素にアクセスすることができる。

関数

関数は以下のように書く。

fn square(x: i32) -> i32 {
    return x * x;
}

戻り値がない場合は以下のようになにも指定しない。

fn greet() {
    println!("hello");
}

セミコロンが付いていない行を最後に書いた場合、式の結果が関数の戻り値になる。

fn square(x: i32) -> i32 {
    x * x
}

関数を変数に代入する関数ポインタを使うこともできる。

fn cube(x: i32) -> i32 {
    x * x * x
}

fn main() {
    let f: fn(i32) -> i32 = cube;
    println!("{}", f(3)); // => 27

コメント

C言語系のコメントの書き方がそのまま使える。

// 一行コメント
let x = 10; // 一行コメント
/*
複数行コメント
abc
def
*/

これらに加えてドキュメント用のコメントを書くことができる。

/// 二乗した値を返す
/// 
/// # 実行例
/// ```
/// square(5); // 25
/// ```
fn square(x: i32) -> i32 {
    x * x
}

///を使って関数などのドキュメントコメントを書ける。 このコメントの中ではMarkdownを使うことができる。

///はドキュメントのあとに続く要素にコメントがつけられるが、//!を使えばファイル全体やモジュールなどにコメントをつけられる。

//! # 計算用ライブラリ
//!
//! 数値計算の関数を提供します。
//! ...

if

他の言語と比べてほとんど違いはない。

let x = 3;
let valid = true;

if x == 3 {
    println!("x is 3");
}

if !valid {
    println!("valid is false");
} else {
    println!("valid is true");
}

// x is 3
// valid is true

加えて、rustではifは文ではなく式になるので以下のようにifの結果を代入したりすることができる。

let x = 5;

let y = if x == 5 { 10 } else { 15 }; // y = 10

ループ

ループの構文には以下の3つがある。

loop

無限ループを実行する。breakで途中で抜けることができる。

let mut i = 0;
loop {
    i += 1;
    println!("i is {}", i);
    if i == 10 {
        break;
    }
}

while

こちらはC言語系とほぼ同じです。

let mut i = 0;
while i != 9 {
    i += 1;
    println!("i is {}", i);
}

無限ループを書くときはwhile true { … }ではなく、loop { … }を使うが推奨されている。

for

以下のように開始値と終了値を指定して書く。

for i in 0..10 {
    println!("i is {}", i);
}

0から9までの数字を表示します。

ループの中ではbreakで抜けたり、continueで次のループに移ることができる。 これはC言語系と同じですね。

その他にループにラベルをつけることができる。 これは二重ループから一気に抜けるときに便利です。

'outer: for y in 0..10 {
    for x in 0..10 {
        if x % 5 == 0 {
            break 'outer;
        }
    }
}

break 'outerで一気に外側のforから抜けられます。