【Rust】Rust ~ 変数 / データ型 ~

◾️はじめに

今回は、Rustの変数とデータ型について扱う

目次

【1】変数・定数
 1)let
 2)mut
 3)シャドーイング
 4)const
【2】Rustの基本データ型
 1)整数
 2)実数
 3)論理
 4)文字
【3】型変換
 0)使用上の注意:Rustには暗黙の型変換はない
 1)キャスト ~ as ~
 2)From / Intoトレイト
 3)TryFrom / TryIntoトレイト

【1】変数・定数

1)let

* 変数 は、「let」で定義する

使用上の注意

* Rust の変数は、標準で不変(immutable) = 変更不可

コンパイルエラー例

fn main() {
    let x = 5;
    println!("The value of x is: {}", x);
    x = 6;
    println!("The value of x is: {}", x);
}
/*
error[E0384]: cannot assign twice to immutable variable `x`
 --> src/main.rs:4:5
  |
2 |     let x = 5;
  |         - first assignment to `x`
3 |     println!("The value of x is: {}", x);
4 |     x = 6;
  |     ^^^^^ cannot assign twice to immutable variable
  |
help: consider making this binding mutable
  |
2 |     let mut x = 5;
  |         +++
*/

2)mut

* mutable(可変)にしたい場合は、「let mut」を使う

修正例

fn main() {
    let mut x = 5; // ★ここを修正
    println!("The value of x is: {}", x);
    x = 6;
    println!("The value of x is: {}", x);
}

3)シャドーイング

* mut 以外で、以下のように「シャドーイング(shadowing)」
 と言う機能を使っても対応は可能

修正例 (シャドーイング)

fn main() {
    let x = 5;
    println!("The value of x is: {}", x);
    let x = 6; // ★ここを修正
    println!("The value of x is: {}", x);
}

シャドーイング(shadowing) とは?

* 同じ名前の変数を“再宣言”して、
 以前の変数を隠してしまう(shadow=影にする)機能

シャドーイング vs mut

* mut ではデータ型は変更できないが、シャドーイングでは可能

4)const

* 定数は、「const」で定義

https://doc.rust-jp.rs/rust-by-example-ja/custom_types/constants.html

const MAX_POINTS: u32 = 100_000;

【2】Rustの基本データ型

https://doc.rust-jp.rs/book-ja/ch03-02-data-types.html

1)整数

Size Javaの場合 符号付き 符号なし
8-bit byte i8 u8
16-bit short i16 u16
32-bit int i32 u32
64-bit i64 u64
arch - isize usize

2)実数

Size Javaの場合 Rust
32-bit float f32
64-bit double f64

3)論理

* bool (true / false)
 => これは、一般のプログラムと同じ

4)文字

Type Javaの場合 Rust Example
文字 char char let c = 'z';
文字列 string str / String let alice = String::from("I like dogs");

https://doc.rust-jp.rs/rust-by-example-ja/std/str.html

String

* 有効なUTF-8の配列であることを保証されたバイトのベクタ(Vec<u8>)として保持

&str

* 有効なUTF-8の配列のスライス(&[u8])で、いつでもStringに変換することができ

【3】型変換

https://doc.rust-jp.rs/rust-by-example-ja/conversion.html

0)使用上の注意:Rustには暗黙の型変換はない

https://doc.rust-jp.rs/rust-by-example-ja/types/cast.html

より抜粋
~~~~
Rustはプリミティブ型における強制的な型変換を暗黙に行うことはありません。
しかし明示的に行うこと(casting)は可能です。
その場合asキーワードを使用します。 << 次項参照
~~~~

コンパイルエラー例

// 以下を実行するとコンパイルエラーになる
fn main() {
    let result = 1 + 1.0;
    println!("result = {}", result);
}

エラーメッセージ

error[E0277]: cannot add a float to an integer
 --> src/main.rs:2:20
  |
2 |     let result = 1 + 1.0;
  |                    ^ no implementation for `{integer} + {float}`
  |
  = help: the trait `Add<{float}>` is not implemented for `{integer}`

1)キャスト ~ as ~

fn main() {
    let result = 1 as f32 + 1.0;
    println!("result = {}", result);
}

https://doc.rust-jp.rs/rust-by-example-ja/types/cast.html

2)From / Intoトレイト

* 型変換を行うジェネリックなトレイト

https://doc.rust-jp.rs/rust-by-example-ja/conversion/from_into.html

例1:strからStringへの型変換

let my_str = "hello";
let my_string = String::from(my_str);

例2:自作の型のFrom/Intoトレイト

use std::convert::From;

#[derive(Debug)]
struct Number {
    value: i32,
}

impl From<i32> for Number {
    fn from(item: i32) -> Self {
        Number { value: item }
    }
}

fn main() {
    // ★fromトレイトの例
    let num = Number::from(30);
    println!("My number is {:?}", num);

    // ★intoトレイトの例
    let int = 5;
    // 自作の型にFromトレイトが実装されていたら
    // Intoは必要に応じてそれを呼び出す(intoを実装していないのに)
    let num: Number = int.into();
    println!("My number is {:?}", num);
}

3)TryFrom / TryIntoトレイト

* 失敗する可能性のある型変換を行うジェネリックなトレイト
 => 失敗する可能性のあるため、Result型で返す

https://doc.rust-jp.rs/rust-by-example-ja/conversion/try_from_try_into.html

use std::convert::TryFrom;
use std::convert::TryInto;

#[derive(Debug, PartialEq)]
struct EvenNumber(i32);

impl TryFrom<i32> for EvenNumber {
    type Error = ();

    fn try_from(value: i32) -> Result<Self, Self::Error> {
        if value % 2 == 0 {
            Ok(EvenNumber(value))
        } else {
            Err(())
        }
    }
}

fn main() {
    // TryFrom
    let result1 = EvenNumber::try_from(8);
    println!("{:?}", result1); // Ok(EvenNumber(8))
    let result2 = EvenNumber::try_from(5);
    println!("{:?}", result2); // Err(())

    println!("******");

    // TryInto
    let result3: Result<EvenNumber, ()> = 8i32.try_into();
    println!("{:?}", result3); // Ok(EvenNumber(8))
    let result4: Result<EvenNumber, ()> = 5i32.try_into();
    println!("{:?}", result4); // Err(())
}

関連記事

Rust ~ 環境構築編 ~
https://dk521123.hatenablog.com/entry/2023/04/22/234808
Rust ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2025/11/26/224648
Rust ~ 制御文 ~
https://dk521123.hatenablog.com/entry/2025/12/07/234508
Rust ~ 複合型 / コレクション ~
https://dk521123.hatenablog.com/entry/2025/12/06/004709
Rust ~ Option型 ~
https://dk521123.hatenablog.com/entry/2025/12/01/223443
Rust ~ Error handling(Result型 / ?演算子) ~
https://dk521123.hatenablog.com/entry/2025/12/02/000346