はじめに
Rustは安全性とパフォーマンスを両立するシステムプログラミング言語です。メモリ安全性をコンパイル時に保証します。
Hello World
fn main() {
println!("Hello, World!");
}
# コンパイル&実行
rustc main.rs
./main
# Cargoを使う場合
cargo new hello_world
cd hello_world
cargo run
変数
不変変数と可変変数
// 不変(デフォルト)
let x = 5;
// x = 6; // エラー!
// 可変
let mut y = 5;
y = 6; // OK
// 定数
const MAX_POINTS: u32 = 100_000;
シャドーイング
let x = 5;
let x = x + 1; // 新しいxを作成
let x = x * 2; // さらに新しいx
// 型も変えられる
let spaces = " ";
let spaces = spaces.len(); // 文字列から数値へ
データ型
スカラー型
// 整数
let i8_val: i8 = 127;
let i16_val: i16 = 32767;
let i32_val: i32 = 2147483647;
let i64_val: i64 = 9223372036854775807;
let i128_val: i128 = 170141183460469231731687303715884105727;
let isize_val: isize = 100; // アーキテクチャ依存
// 符号なし整数
let u8_val: u8 = 255;
let u32_val: u32 = 4294967295;
// 浮動小数点
let f32_val: f32 = 3.14;
let f64_val: f64 = 3.14159265359; // デフォルト
// 真偽値
let t: bool = true;
let f: bool = false;
// 文字(Unicode)
let c: char = 'あ';
let emoji: char = '😊';
複合型
// タプル
let tup: (i32, f64, u8) = (500, 6.4, 1);
let (x, y, z) = tup; // 分割代入
let first = tup.0; // インデックスアクセス
// 配列(固定長)
let arr: [i32; 5] = [1, 2, 3, 4, 5];
let first = arr[0];
let same = [3; 5]; // [3, 3, 3, 3, 3]
関数
fn main() {
println!("{}", add(3, 5));
greet("太郎");
}
fn add(a: i32, b: i32) -> i32 {
a + b // 最後の式が戻り値(セミコロンなし)
}
fn greet(name: &str) {
println!("こんにちは、{}さん!", name);
}
// 早期リターン
fn divide(a: i32, b: i32) -> Option<i32> {
if b == 0 {
return None;
}
Some(a / b)
}
条件分岐
if式
let age = 20;
if age >= 20 {
println!("成人です");
} else if age >= 13 {
println!("ティーンエイジャーです");
} else {
println!("子供です");
}
// if式(値を返す)
let status = if age >= 20 { "成人" } else { "未成年" };
match式
let number = 3;
match number {
1 => println!("一"),
2 => println!("二"),
3 => println!("三"),
4 | 5 => println!("四か五"),
6..=10 => println!("6から10"),
_ => println!("その他"),
}
// 値を返す
let result = match number {
1 => "one",
2 => "two",
3 => "three",
_ => "other",
};
// パターンマッチング
let point = (0, 5);
match point {
(0, y) => println!("x軸上、y={}", y),
(x, 0) => println!("y軸上、x={}", x),
(x, y) => println!("({}, {})", x, y),
}
ループ
// loop(無限ループ)
let mut count = 0;
let result = loop {
count += 1;
if count == 10 {
break count * 2; // 値を返してbreak
}
};
// while
let mut n = 0;
while n < 5 {
println!("{}", n);
n += 1;
}
// for
for i in 0..5 {
println!("{}", i); // 0, 1, 2, 3, 4
}
for i in 0..=5 {
println!("{}", i); // 0, 1, 2, 3, 4, 5
}
// 配列の反復
let arr = [10, 20, 30];
for element in arr.iter() {
println!("{}", element);
}
for (index, element) in arr.iter().enumerate() {
println!("{}: {}", index, element);
}
文字列
// 文字列スライス(&str)- 不変
let s1: &str = "Hello";
// String - 可変、ヒープに格納
let mut s2 = String::from("Hello");
s2.push_str(", World!");
s2.push('!');
// 変換
let s3 = "hello".to_string();
let s4: &str = &s2;
// 結合
let s5 = format!("{} {}", "Hello", "World");
let s6 = s1.to_string() + " World";
// 長さ
let len = s2.len(); // バイト数
let chars = s2.chars().count(); // 文字数
// スライス
let hello = &s2[0..5];
// 検索
if s2.contains("World") {
println!("含まれています");
}
ベクタ(可変長配列)
// 作成
let mut v: Vec<i32> = Vec::new();
let v2 = vec![1, 2, 3]; // マクロ
// 追加
v.push(1);
v.push(2);
v.push(3);
// アクセス
let first = v[0];
let first_safe = v.get(0); // Option<&i32>
// 反復
for i in &v {
println!("{}", i);
}
for i in &mut v {
*i += 10;
}
// 削除
v.pop();
まとめ
- Rustは安全性重視のシステムプログラミング言語
- 変数はデフォルトで不変、
mutで可変に match式で強力なパターンマッチングString(所有権あり)と&str(借用)を区別Vec<T>は可変長配列
次回は所有権について学びます。