Rust をやってみる

/
#rust

同居人から風邪を貰い、熱や咳に鼻水と症状が続き、普段通りの生活が阻害されていたので、Rust を触ってみることにした。以前に RustではじめるOpenGL | インプレス NextPublishing という本を読むにあたって、一度だけ Hello world までの初歩的なことはしていた。

はじめに

Rust を触ったら、案の定大変だった・分からなさ過ぎた。でも楽しかった。Rust を使って何かサービスを作る予定は全くないが、過去に勝った技術本を写経したり、画像処理をやるなどして Rust で遊びたい。 ※メモ書きなので他者が読んでも得るものはありません。noindex を設定してすらいます。

Rust とは

安全性と高パフォーマンスを両立させたシステムプログラミング言語。メモリ安全性を保証し、並行処理も安全に行えるため、信頼性の高いソフトウェア開発に適しています。近年、Next.js や Biome といったフロントエンドの FW や開発ツールが Rust を採用し始めている。

https://github.com/biomejs/biome

Web ブラウザ上で高速実行が可能で複雑な計算やゲーム開発・マルチメディア処理に適しているとされるバイナリ形式の命令セットで WebAssembly (Wasm) というものがあるが、これを作成するのに Rust などが用いられている。実際に AmazonPrimeVideo の動画再生のパフォーマンス改善に Rust コードから生成した Wasm が利用されたというニュースが2022年にあった。

https://www.publickey1.jp/blog/22/amazon_prime_videowebassemblywasm_vm.html

準備

Ubuntu on WSL2 で行った。他の言語の環境構築と比較して、非常に簡単だった気がした。

Terminal window
1
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
2
echo 'export PATH=$HOME/.cargo/bin:$PATH' | tee -a .bashrc

Rust 用の VSCode 拡張機能として、下4つを入れた。Rust を軽く触るだけなら、最上段の1つだけで良いとおもった。

参照

Playground

Rust Ja Docs をよみつつ、エディターで試せるコードは試すようにした。『JavaScript におけるあれか、Ruby におけるあれか、C++で似たやつあったな・・』と思いながら触っていったが、よく分からない箇所はまあまああった。

よく分からなかった箇所・理解が進んでいない箇所

シングルクォテーション '1つを使った用法もあって、分からない箇所も忘れていそう

  • 配列とベクタとスライス
    • 何となく分かった気もするが、まだ適切に使い分ける事は大変そう
  • クロージャ
    • わからない
  • トレイと
    • わからない
  • &'a, <'a>
    • 分からない上に、覚えづらいし、検索し辛い・・

分かった気になっただけの箇所もあると思われるし、分かってない箇所を覚えてない可能性もあるので、プログラムを書いてはドキュメントに戻り・・・を繰り返すしかなさそう。

Codes

FizzBuzz

String なのか &str といった箇所はまだ微妙。1..=100 という箇所は Ruby と似ているが少し違うので混同しそうだと思った。型を書くことについては TypeScript で割と慣れている気がした。

main.rs
1
fn main() {
2
for num in 1..=100 {
3
println!("{}", fizzbuzz(num));
4
}
5
}
6
7
fn get_fizz_buzz_if(num: u32) -> String {
8
if num % 2 == 0 && num % 3 == 0 {
9
"FizzBuzz".to_string()
10
} else if num % 2 == 0 {
11
"Fizz".to_string()
12
} else {
13
"Buzz".to_string()
14
}
15
}
16
17
fn get_fizz_buzz_match(num: u32) -> String {
18
match (num % 3, num % 5) {
19
(0, 0) => "FizzBuzz".to_string(),
20
(0, _) => "Fizz".to_string(),
21
(_, 0) => "Buzz".to_string(),
22
_ => num.to_string(),
23
}
24
}

統計っぽいこと

Rust にも as があるんだと思った。JSDoc の様なドキュメンテーションコメントの書き方を知った。この Zenn の Rustのドキュメンテーションコメントの書き方 が詳しかった。

main.rs
1
use std::collections::HashMap;
2
3
fn main() {
4
let numbers: Vec<i32> = vec![1, 2, 2, 3, 4, 5, 5, 5, 6, 7];
5
6
let largest: i32 = calculate_largest(&numbers);
7
let mean: f64 = calculate_mean(&numbers);
8
let median: f64 = calculate_median(&numbers);
9
let mode: i32 = calculate_mode(&numbers);
10
11
println!("Largest: {}", largest);
12
println!("Mean: {}", mean);
13
println!("Median: {}", median);
14
println!("Mode: {}", mode);
15
}
16
17
fn calculate_largest(numbers: &Vec<i32>) -> i32 {
18
let mut largest = numbers[0];
19
20
for &item in numbers.iter() {
21
if item > largest {
22
largest = item
23
}
24
}
25
26
largest
27
}
28
29
/// 平均値
30
fn calculate_mean(numbers: &Vec<i32>) -> f64 {
31
let sum: i32 = numbers.iter().sum();
32
let count = numbers.len();
33
sum as f64 / count as f64
34
}
35
36
fn calculate_median(numbers: &Vec<i32>) -> f64 {
37
//! 中央値
38
let mut sorted_numbers: Vec<i32> = numbers.clone();
39
sorted_numbers.sort();
40
41
let count = sorted_numbers.len();
42
if count % 2 == 0 {
43
(sorted_numbers[count / 2 - 1] + sorted_numbers[count / 2]) as f64 / 2.0
44
} else {
45
sorted_numbers[count / 2] as f64
46
}
47
}
48
49
fn calculate_mode(numbers: &Vec<i32>) -> i32 {
50
//! 最頻値
51
let mut occurrences = HashMap::new();
52
53
for &value in numbers {
54
*occurrences.entry(value).or_insert(0) += 1;
55
}
56
57
occurrences
58
.into_iter()
59
.max_by_key(|&(_, count)| count)
60
.map(|(value, _)| value)
61
.unwrap()
62
}