Open18
Rustの勉強を始める
dbg!()
- デバッグに便利なマクロ
- 式と結果が標準エラーを出力
- println!などのマクロと違ってそのまま式が出力され、出力後に値を返す点が異なる
mut: mutable variable
プロジェクトの作り方
cargo new PRJ
コンパイル & 実行
cargo run
コメントの書き方
-
//! ...
inner line (行末までがコメント。 // と同様) -
/*! ... */
inner block (囲まれた範囲内がコメント。 /* ... */ と同様) -
/// ...
outer line -
/** ... */
outer block
!
とは?
演算子マクロ展開
(付録B:演算子と記号 - The Rust Programming Language 日本語版)
- マクロとは
マクロ
本全体を通じてprintln!のようなマクロを使用してきましたが、マクロがなんなのかや、 どう動いているのかということは完全には探究していませんでした。 Rustにおいて、マクロという用語はある機能の集合のことを指します:macro_rules!を使った 宣言的 (declarative) マクロと、3種類の 手続き的 (procedural) マクロ:
- 構造体とenumにderive属性を使ったときに追加されるコードを指定する、カスタムの#[derive]マクロ
- 任意の要素に使えるカスタムの属性を定義する、属性風のマクロ
- 関数のように見えるが、引数として指定されたトークンに対して作用する関数風のマクロ
です。
(マクロ - The Rust Programming Language 日本語版)
?演算子
for / while / loop
- while: 条件を満たすまで計算をし続ける
use rand::Rng;
fn main() {
let mut num_loop = 0;
let mut num_add = 0;
while num_add < 6 {
let x = rand::rng().random_range(0..100);
num_loop += 1;
println!("loop No.{}", num_loop);
if x > 50 {
println!("乱数が50より大きいので1足します");
num_add += 1;
if num_add >= 6 {
println!("5に到達したので、break します");
break; //exit from loop
}
} else {
println!("乱数が50以下なのでそのままの値です -> {}", num_add);
}
}
}
多重break
ループが入れ子になっている場合、内側のループだけでなく、外側のループからも一気に脱出したいときは下記のようなコードでかける
'soto: for i in 1..=3 { // 外側のfor ループに 'sotoという名前をつける
for j in 1..=3 {
if i * j == 8 {
println!("外側まで一気に脱出");
break 'soto // 'sotoの外側に脱出
}
}
}
match構文
match 数字 {
パターン1 => {
// run
},
パターン2 => {
// run
},
_ => {
// それ以外
}
}
use rand::Rng;
fn main() {
let switch_no = rand::rng().random_range(1..=2);
match switch_no {
1 => {
println!("match 1");
},
2 => {
println!("match 2");
},
_ => unreachable!(),
}
}
列挙型と構造体
- 列挙型 / Enumerated type: あらかじめ定義された値のみ取りうる型
eunm 型名 {
列挙子1,
列挙子2
}
let a = 型名::列挙子
で変数を付与できる
- 構造体 / : 複数の変数をまとめて管理することができるデータ構造。
struct NAME {
name1: 変数,
name2: 変数2,
}
println!()
fn main() {
let a = [1, 2, 3];
println!("a = {}", a);
}
// }", a);
// ^ `[{integer}; 3]` cannot be formatted with the default formatter
というコンパイルエラーが出てしまう。
fn main() {
let a = [1, 2, 3];
println!("a = {:?}", a);
}
のように:?
を加えるとOK
in format strings you may be able to use
{:?}
rustでvectorに値を追加する
fn main() {
let mut a = [1, 2, 3];
a.push([4]);
println!("a = {:?}", a);
}
はエラー
fn main() {
let mut a = vec![1, 2, 3];
a.push(4);
println!("a = {:?}", a);
}
のように、vec!マクロでベクター指定
rustでvectorいろいろ
fn main() {
let mut a = vec![3, 5, 7];
// 末尾に追加 pop
a.push(6);
println!("a = {:?}", a);
println!("length = {}", a.len());
// 任意の位置に追加 insert
a.insert(0, 1);
println!("a = {:?}", a);
a.insert(2, 1);
println!("a = {:?}", a);
// 末尾を削除して Option<T>で返す
let b = a.pop();
println!("b = {:?}", b);
println!("a = {:?}", a);
// 指定した位置を削除 remove
a.remove(2);
println!("a = {:?}", a);
}
// a = [3, 5, 7, 6]
// length = 4
// a = [1, 3, 5, 7, 6]
// a = [1, 3, 1, 5, 7, 6]
// b = Some(6)
// a = [1, 3, 1, 5, 7]
// a = [1, 3, 5, 7]
loopとrangeに関して
fn main() {
for n in 1..3 {
println!("loop range:1..3 n is {}", n)
}
for n in 1..=3 {
println!("loop range:1..=3 n is {}", n)
}
for n in 0..=3 {
println!("loop range:0..=3 n is {}", n)
}
let set = vec!["a", "b", "c"];
for i in set.iter() {
println!("loop range:set.iter() {}", i);
}
}
関数
fn FNNAME() -> 戻り値の型 {
// 処理,,,
}
ブロック式
fn main() {
let some_val: i32 = {
let tmp = 2;
tmp
}
}
-
{
で囲われたコードブロックもrustでは式として処理 - 最後の式の値が使われる。
;
は書かない点に注意 - 変数
tmp
はこのコードブロックの中のみで有効。この外側では使えない