第17回です。
前回はこちら。
[第17回の様子]
2021/11/11に第17回を開催した。
諸事情により今週は木曜開催。文化の日が休みだったので間が空いてしまった...。
内容としてはRust By Example 日本語版の「5.4. エイリアス」、「6. 型変換」、「6.1. FromおよびInto」に取り組んだ。
曜日がいつもと変わったせいか、参加者はちょっと減って、全部で5人。
[学んだこと]
- 5.4. エイリアス
type
文を使うと既存の型にエイリアスをつけられる(UpperCamelケースのみ)
// `NanoSecond` を `u64`の別名として使用する。 type NanoSecond = u64; type Inch = u64; fn main() { // `NanoSecond` = `Inch` = `u64_t` = `u64`. let nanoseconds: NanoSecond = 5 as u64_t; let inches: Inch = 2 as u64_t; }
- UpperCamelケースを使わない場合は警告がでる
type u64_t = u64; warning: type `u64_t` should have an upper camel case name --> src/main.rs:9:6 | 9 | type u64_t = u64; | ^^^^^ help: convert the identifier to upper camel case: `U64T` | = note: `#[warn(non_camel_case_types)]` on by default
type NanoSecond = u64; type Inch = u64; fn main() { let nanoseconds: NanoSecond = 5 as u64_t; let inches: Inch = 2 as u64_t; // 異なるエイリアスどうしでも演算できてしまう println!("{} nanoseconds + {} inches = {} unit?", nanoseconds, inches, nanoseconds + inches); // 5 nanoseconds + 2 inches = 7 unit? }
- エイリアスは冗長な型宣言を減らすために利用される
type IoResult<T> = Result<T, IoError>;
- 6. 型変換
- Rustはトレイトを用いて型変換を行う:FromやIntoなど
- 6.1. FromおよびInto
- Fromトレイトはある型を別の型から作る方法を定義するもの
- strからStringへの型変換は以下のように行う
let my_str = "hello"; let my_string = String::from(my_str);
- 自作の型(以下のNumber)への型変換は以下のように定義する
use std::convert::From; #[derive(Debug)] struct Number { value: i32, } impl From<i32> for Number { fn from(item: i32) -> Self { Number { value: item } } } fn main() { let num = Number::from(30); println!("My number is {:?}", num); // My number is Number { value: 30 } }
- IntoはFromの逆で、fromを呼び出す形になる
use std::convert::From; #[derive(Debug)] struct Number { value: i32, } impl From<i32> for Number { fn from(item: i32) -> Self { println!("From called"); Number { value: item } } } fn main() { let int = 5; let num: Number = int.into(); // from()が呼ばれ、From calledが出力される println!("My number is {:?}", num); }
- into()を呼び出す場合は、左辺に型定義が必須となる
let int = 5; let num = int.into(); // 以下のコンパイルエラー error[E0282]: type annotations needed --> src/main.rs:17:9 | 17 | let num = int.into(); | ^^^ consider giving `num` a type
- Number型をi32に変換するためのIntoを実装すると次のようになる
use std::convert::From; use std::convert::Into; #[derive(Debug)] struct Number { value: i32, } impl From<i32> for Number { fn from(item: i32) -> Self { println!("From called."); Number { value: item } } } impl Into<i32> for Number { fn into(self) -> i32 { println!("Into called"); self.value } } fn main() { let int = 5; let num: Number = int.into(); // From called. println!("My number is {:?}", num); // My number is Number { value: 5 } let int2: i32 = num.into(); // Into called println!("int2: {}", int2); // int2: 5 }
[まとめ]
モブプログラミングスタイルでRust dojoを開催した。
久しぶりにドライバをやって緊張した。
今週のプルリクエストはこちら。