社内研修で紹介したRustの
「コンパイル通る?通らない?クイズ」をまとめました。

前提

    • チュートリアルをかじりだしたレベルのRust初心者向けです

主にJava -> Pythonと触ってきた著者がRust勉強のとっかかりで「そうなの!?」と思った点をクイズにしました

cargo build で動作確認しています

クイズ

    • 全部で5問あります。

3択でお答えください。

コンパイルが通る(warningが出ない)
コンパイルが通る(warningが出る)
コンパイルは通らない(errorが出る)

答えは折りたたんであります。

Q1

fn main() {
    let test: int = 123; 

    println!("{}", test);
}
Q1の答えコンパイルは通らない(errorが出る)

error[E0412]: cannot find type `int` in this scope
–> src/main.rs:2:15
|
2 | let test: int = 123;
| ^^^ not found in this scope

Rustは「int」という名前の型を標準で定義していません。

整数型の詳細はチュートリアルをご参照ください。
https://doc.rust-jp.rs/book/second-edition/ch03-02-data-types.html#a%E6%95%B4%E6%95%B0%E5%9E%8B

「大体『int』はあるでしょ~」で書いてはいけません(自分への戒め)。


Q2

fn main() {
    let mut test = 123;

    assert_eq!(test, 1_23_i8); 
}
Q2の答えコンパイルが通る(warningが出る)

warning: variable does not need to be mutable
–> src/main.rs:2:9
|
2 | let mut test = 123;
| —-^^^^
| |
| help: remove this `mut`
|
= note: `#[warn(unused_mut)]` on by default

ミュータブルである必要がない変数をミュータブルにしてはいけません。

「このmutを消しなさい」と超具体的に教えてくれます。
Rustコンパイラの愛を感じます。

1_23_i8 については問題ありません。
数値リテラルはアンダーバーで区切ることができ、サフィックスで型の指定も可能です。

詳細はチュートリアルをご参照ください。
https://doc.rust-jp.rs/book/second-edition/ch03-02-data-types.html#a%E6%95%B4%E6%95%B0%E5%9E%8B


Q3

fn main() {
    let mut test = 0;

    test = 456;

    assert_eq!(test, 456); 
}
Q3の答えコンパイルが通る(warningが出る)

warning: value assigned to `test` is never read
–> src/main.rs:2:13
|
2 | let mut test = 0;
| ^^^^
|
= note: `#[warn(unused_assignments)]` on by default
= help: maybe it is overwritten before being read?

一度も使わない変数どころか、一度も使わない値に対してもwarningを出して教えてくれます。
Rustコンパイラの愛が重い。


Q4

fn main() {
    let test: String = "hogehoge"; 

    println!("{}", test);
}
Q4の答えコンパイルは通らない(errorが出る)

error[E0308]: mismatched types
–> src/main.rs:2:24
|
2 | let test: String = “hogehoge”;
| —— ^^^^^^^^^^
| | |
| | expected struct `std::string::String`, found `&str`
| | help: try using a conversion method: `”hogehoge”.to_string()`
| expected due to this

Rustは文字列リテラルとString型を厳密に区別します。
変数test はString型で宣言されていますが、”hogehoge”は文字列リテラルです。
よって型不一致です。

「”hogehoge”.to_string()を試してみたら?」と超具体的に提案してくれます。
Rustコンパイラの母性を感じます。


Q5

fn main() {
    let test: String = "hogehoge".to_string();
    println!("{}", test);

    let test: i32 = 123;
    println!("{}", test);
}
Q5の答えコンパイルが通る(warningが出ない)

「同一スコープ内に同一名の変数の宣言はNGでは?」と思いきや、
RustはシャドーイングがあるのでOKなのです。

シャドーイングの詳細はチュートリアルをご参照ください。
https://doc.rust-jp.rs/book/second-edition/ch03-01-variables-and-mutability.html#a%E3%82%B7%E3%83%A3%E3%83%89%E3%83%BC%E3%82%A4%E3%83%B3%E3%82%B0

お疲れさまでした!

最後までお付き合いくださりありがとうございました。

Rustを触っていると特に自分の未熟さが明瞭になり
日々心をえぐられていますが、挫折しないよう頑張ります。