第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を開催した。
久しぶりにドライバをやって緊張した。
今週のプルリクエストはこちら。