Hagakun blog
hero image[object Object]

【Chapter2】クジラ飛行机さんの Rust 本を読んで Rust を勉強する


やっと手を動かして考えればよくわかる 高効率言語 Rust 書きかた・作りかた が届いたので、あらためて Rust を勉強しようと思う。

モチベーション

ビンゴカードの作成

rand クレートの shuffle() がほかの言語と比較して変わっている

rust
use rand::prelude::*;
let mut rng = rand::thread_rng();
nums.shuffle(&mut rng);

最初から配列に .shuffle() が生えているワケではなくて、 rand パッケージから thread_rng() を呼び出すと .shuffle() が使えるようになる仕様。
また、**shuffle()**のなかに乱数ジェネレータ rng を渡す必要がある。

Result 型のカンタンな使い方

rust
let mut s = String::new();
// ユーザーの入力を受け取るメソッド readline()は返り値がResult型
// expect()はResult型を受け取り、エラーがあったら()の中身を返す
std::io::stdin().readline().expect('error')
//unwrap()はResult型を受け取り、エラーがあったらpanic()を起こす
std::io::stdin().readline().unwrap()
//matchはResult型を受け取り、Result型の返り値であるOkかErrの処理を記述できる
match std::io::stdin().readline() {
Ok(line) => {
println!("{}", line);
},
Err(e) => {
println!("{}", e);
}
}
//

アンケート集計

この章では、HashMap と Option 型について言及しているのでメモ。 HashMap は他言語での Map に対応する。

rust
//HashMapの使い方について
use std::collections::HashMap;
//初期化
let mut map = HashMap::new();
//要素の追加
map.insert("key1", "value1");
map.insert("key2", "value2");
let k1 = map['key1'] // key1
let ke = map['key9999'] // panic!
//panicを避けるためにget()を使うことができる
//get()は、Option型を返す。
//Result -> Ok(value) or Err(error) に対して、
//Option -> Some(value) or None
match map.get("key1") {
Some(value) => println!("{}", value),
None => println!("key1 is not found"),
}

unwrap_or() [p195]

Option 型で使えるメソッド。Option 型は NoneSome を返すものだが、unwrap_or()を使うと None の場合に panic させずに指定した値を返すことができる。 match 文を使うこともできるが、簡便に使いたいときは便利。

rust
let name = path.to_str().unwrap_or("default");

再帰的な呼び出しを tree コマンドの実装で確認する

rust
use std::{env, path};
fn main() {
let args: Vec<String> = env::args().collect();
let mut target_dir = ".";
if args.len() >= 2 {
target_dir = &args[1];
}
// PathBufを取得
let target = path::PathBuf::from(target_dir);
println!("{}", target_dir);
tree(&target, 0);
}
// tree構造を出力する
fn tree(target: &path::PathBuf, level: isize) {
let files = target.read_dir().expect("不正なパス");
for ent in files {
let entry = ent.unwrap();
let path = entry.path();
// levelに応じたintentを出力
for _ in 0..level {
print!("| ");
}
let fname = path.file_name().unwrap().to_string_lossy();
// pathがディレクトリの時はインデントを追加したうえで再帰的に呼び出す。
if path.is_dir() {
println!("|--<{}>", fname);
tree(&path, level + 1);
continue;
}
println!("|--{}", fname);
}
}