Hagakun blog
hero image[object Object]

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


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

モチベーション

1 章の学習

まず、p66 までの部分で for ループと if の表現を復習。
Python と比較しながら解説していくため、非常に理解しやすい形になっていてよい。
この時点では特に記法の不明点等はない。

rust
fn main() {
// for ループは .. を使って表現し、条件に()が不要
for y in 1926..2026 {
// print は改行を含まない
print!("西暦{}年 = ", y);
if(y < 1989){
println!("昭和{}年", y-1926+1);
}
else if(y == 1989){
println!("平成元年");
}
else if(y < 2019){
println!("平成{}年", y-1989+1);
} else if(y == 2019){
println!("令和元年");
} else {
println!("令和{}年", y-2019+1);
}
}
}

1-9 シーザー暗号について

文字コード(i16)と文字列リテラルをasでカンタンにキャストできる。
ちなみに、ユニコードを取得したいときはu32にキャストすると良い。

rust
fn encrypt(text:&str, shift:i16) -> String{
let code_a = 'a' as i16; // 'a'の文字コードを取得している
let code_z = 'z' as i16;
let mut result = String::new();
//文字列リテラル.chars()で一文字づつ取り出すことができる。
for ch in text.chars() {
let code = ch as i16; // シーザー暗号とは文字列コードをズラすことなので、i16にキャストしている。
if code_a <= code && code <= code_z {
let new_code = (code - code_a + shift + 26 ) % 26 + code_a;
result.push(new_code as u8 as char);
}
}
return result;
}
fn main(){
let result = encrypt("abcdefghijklmnopqrstuvwxyz", 1);
println!("{}", result);
}

クロージャー

クロージャーを定義すると、処理をカンタンに表現できる

rust
let x2 = |x| x*2;
println!("{}", x2(2)); // 4

クロージャーでシーザー暗号を効率的に実装

クロージャーはなんだか方程式みたい。
未定義の c を使って、計算式を先に定義している感じ。

rust
fn encrypt(text:&str, shift:i16) -> String{
let a = 'a' as i16;
let is_as = |c| 'a' <= c && c <= 'z';
let conv = |c| (((c-a+shift+26)%26+a) as u8) as char;
let enc = |c| if is_as(c) { conv(c as i16) } else { c };
return text.chars().map(|c| enc(c)).collect();
}

100 個の素数を求める

rust
fn is_prime(n: usize) -> bool {
for i in 2..n {
if n % i == 0 {
return false;
}
}
return true;
}
fn get_primes(prime: &mut [usize; 100]) {
let mut i = 2;
let mut count = 0;
while count < 100 {
if is_prime(i) {
prime[count] = i;
count += 1;
}
i += 1;
}
}
fn main() {
let mut prime = [0; 100];
get_primes(&mut prime);
println!("{:?}", prime);
}

**get_prime()**の実装の特徴は、primeを参照で渡しているところ。
この場合、prime自体が関数内部で書き変えられる。

usize 型

ポインタと同じサイズの符号なし整数(64 ビット環境では u64 と同じ)

長さが決まっている配列変数の宣言

rust
//長さ固定の場合
let mut prime = [初期値 ; 配列要素数]
//長さが変わる場合は可変配列のベクターを使う
let prime = vec![1,2,3,4,5]

三項演算子っぽい書き方について

Rust には三項演算子はない。
でも if else を使ってかなり似た記述が可能なので、下記にメモしておく。

rust
let x = if 条件 { 真の時の値 } else { 偽の時の値 };