変数と型
プログラムでデータを扱う基本、「変数」と「型」について学びます。
変数とは
変数は「データを入れておく箱」です。
fn main() {
let age = 25; // ageという変数に25を入れる
println!("年齢: {}", age);
}
出力:
年齢: 25
変数の宣言
#![allow(unused)]
fn main() {
let 変数名 = 値;
}
let: 変数を作るキーワード変数名: 好きな名前をつけられる(ルールあり)=: 値を代入する値: 変数に入れるデータ
変数名のルール
#![allow(unused)]
fn main() {
// OK
let age = 25;
let user_name = "太郎";
let totalCount = 100;
let _temp = 0;
// NG
let 123abc = 10; // 数字で始まってはいけない
let my-name = ""; // ハイフンは使えない
let let = 5; // 予約語は使えない
}
慣習: Rustではsnake_case(小文字とアンダースコア)が推奨されます。
#![allow(unused)]
fn main() {
let user_name = "太郎"; // 推奨
let userName = "太郎"; // 動くけど警告が出る
}
型(Type)とは
型は「データの種類」です。
#![allow(unused)]
fn main() {
let age = 25; // 整数型
let height = 170.5; // 浮動小数点型
let name = "太郎"; // 文字列型
let is_student = true; // 真偽型
}
Rustは静的型付け言語で、すべての変数には型があります。
基本的な型
整数型
| 型 | サイズ | 範囲 |
|---|---|---|
i8 | 8bit | -128 〜 127 |
i16 | 16bit | -32,768 〜 32,767 |
i32 | 32bit | 約-21億 〜 約21億(デフォルト) |
i64 | 64bit | とても大きい |
u8 | 8bit | 0 〜 255 |
u16 | 16bit | 0 〜 65,535 |
u32 | 32bit | 0 〜 約42億 |
u64 | 64bit | とても大きい |
i: 符号あり(マイナスも扱える)u: 符号なし(0以上のみ)
#![allow(unused)]
fn main() {
let age: i32 = 25;
let count: u32 = 100;
}
通常は型を書かなくてもRustが推論してくれます:
#![allow(unused)]
fn main() {
let age = 25; // i32と推論される
}
浮動小数点型
| 型 | サイズ | 説明 |
|---|---|---|
f32 | 32bit | 単精度 |
f64 | 64bit | 倍精度(デフォルト) |
#![allow(unused)]
fn main() {
let height = 170.5; // f64と推論
let weight: f32 = 65.0; // 明示的にf32
}
真偽型(bool)
#![allow(unused)]
fn main() {
let is_student = true;
let is_adult = false;
}
true(真)またはfalse(偽)の2値のみ。
文字型(char)
#![allow(unused)]
fn main() {
let c = 'A';
let emoji = '😀';
let kanji = '漢';
}
シングルクォート'で囲む。1文字だけ。
文字列型
#![allow(unused)]
fn main() {
let name = "太郎"; // &str型(文字列スライス)
let greeting = String::from("こんにちは"); // String型
}
ダブルクォート"で囲む。文字列は後で詳しく学びます。
型注釈
型を明示的に書くことを型注釈といいます:
#![allow(unused)]
fn main() {
let age: i32 = 25;
let height: f64 = 170.5;
let name: &str = "太郎";
let is_student: bool = true;
}
通常はRustが推論してくれるので省略できますが、書いた方がわかりやすい場合もあります。
不変(immutable)と可変(mutable)
デフォルトは不変
Rustの変数はデフォルトで不変です。
fn main() {
let x = 5;
x = 6; // エラー!
}
エラー:
error[E0384]: cannot assign twice to immutable variable `x`
可変にするには mut
fn main() {
let mut x = 5; // mutをつける
println!("x = {}", x);
x = 6; // OK!
println!("x = {}", x);
}
出力:
x = 5
x = 6
なぜデフォルトが不変なのか?
- バグを減らせる:意図しない変更を防ぐ
- コードが読みやすい:変わらないことが保証される
- 並行処理で安全:複数の処理が同時にアクセスしても安全
「変更する必要がある」ときだけ mut をつける習慣をつけましょう。
シャドーイング
同じ名前の変数を再度宣言することをシャドーイングといいます:
fn main() {
let x = 5;
let x = x + 1; // 新しいxで古いxを「覆い隠す」
let x = x * 2;
println!("x = {}", x); // 12
}
mutとの違い:
- シャドーイング:新しい変数を作る。型も変えられる
mut:同じ変数の値を変える。型は変えられない
#![allow(unused)]
fn main() {
// シャドーイング:型を変えられる
let spaces = " "; // &str
let spaces = spaces.len(); // usize(型が変わった)
// mut:型は変えられない
let mut spaces = " ";
spaces = spaces.len(); // エラー!型が違う
}
定数
変わらない値には定数を使います:
const MAX_POINTS: u32 = 100_000;
fn main() {
println!("最大ポイント: {}", MAX_POINTS);
}
定数の特徴:
constキーワードを使う- 型注釈が必須
- 大文字とアンダースコアで命名(
SCREAMING_SNAKE_CASE) - プログラム全体で使える
まとめ
| 概念 | 説明 |
|---|---|
| 変数 | データを入れる箱。letで作る |
| 型 | データの種類(i32, f64, bool, charなど) |
| 不変 | デフォルト。変更できない |
| 可変 | mutをつけると変更可能 |
| シャドーイング | 同名の変数を再宣言 |
| 定数 | constで宣言。変更不可 |
確認テスト
Q1. Rustの変数のデフォルトの性質は?
mut キーワードをつけます。
Q2. 以下の型のうち、符号なし整数型はどれ?
uで始まる型は符号なし(unsigned)整数型で、0以上の値のみを扱います。iで始まる型は符号あり(signed)で、マイナスの値も扱えます。
Q3. 以下のコードの出力は?let x = 5; let x = x + 1; let x = x * 2; println!("{}", x);
Q4. let count = 0; count = count + 1; このコードのエラーを修正するには?
mut キーワードを追加します。不変の変数に再代入しようとしたのがエラーの原因です。
Q5. 「身長170.5cm」を格納するのに最適な型は?
次のドキュメント: 02_operators.md