第7回です。
前回はこちら。
[第7回の様子]
2021/08/25に第7回を開催した。
今回はちょっと遅れて、無事参加できた。5分遅刻した結果先に始まっていたけど、みんな自律的に動けていて良い。次は遅刻しないようにしよう(そもそも直前にMTGを入れなければよいのだが...)。
内容としてはRust By Example 日本語版の「2.2. タプル」を読んで手を動かした。
参加者は全部で10人。ひさびさの2桁!なかなか盛況である。
今回も、前回終了時に決めておいたメンバーがドライバーを担当。
今週も開催前後のSlackでのやりとりがたくさん🎉

タプルの制約の話。

所有権難しい...。

手を動かしててエライ。

来週はぜひぜひ。

[学んだこと]
- 2.2. タプル
- タプルは値の集合で、()で生成する
let tuple = (10, true);
- 関数が複数の値を返すときに使うらしい
- 様々な型をまとめられる:まとめた値にはインデックスでアクセスできる
let long_tuple = (1u8, 2u16, 3u32, 4u64,
-1i8, -2i16, -3i32, -4i64,
0.1f32, 0.2f64,
'a', true);
println!("long tuple first value: {}", long_tuple.0);
println!("long tuple second value: {}", long_tuple.1);
- タプルのタプルも定義できる
let tuple_of_tuples = ((1u8, 2u16, 2u32), (4u64, -1i8), -2i16);
- タプルの要素は12個までならprintlnで出力できる:13個だとコンパイルエラーになる(printlnしなければ利用可能)
let too_long_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
println!("too long tuple: {:?}", too_long_tuple.4);
// 上記コードは以下のコンパイルエラー
error[E0277]: `({integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer})` doesn't implement `Debug`
--> src/main.rs:39:38
|
39 | println!("too long tuple: {:?}", too_long_tuple);
| ^^^^^^^^^^^^^^ `({integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer})` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
= help: the trait `Debug` is not implemented for `({integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer}, {integer})`
= note: required by `std::fmt::Debug::fmt`
= note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)
- タプルは関数の引数や戻り値に利用できる
fn reverse(pair: (i32, bool)) -> (bool, i32) {
// 分解して別の変数に代入できる
let (integer, boolean) = pair;
// 別のタプルを生成する
(boolean, integer)
}
let pair = (1, true);
println!("pair is {:?}", pair);
// pair is (1, true)
println!("the reversed pair is {:?}", reverse(pair));
// the reversed pair is (true, 1)
- 1要素だけのタプルをつくる場合にはカンマを忘れずに
println!("one element tuple: {:?}", (5u32,));
// one element tuple: (5,)
println!("just an integer: {:?}", (5u32));
// just an integer: 5
- 演習1:Matrix構造体にいい感じの
fmt::Displayトレイトを実装せよ
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);
impl fmt::Display for Matrix {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "( {} {} )\n( {} {} )", self.0, self.1, self.2, self.3)
}
}
let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
println!("{:}", matrix);
// ( 1.1 1.2 )
// ( 2.1 2.2 )
- 演習2:Matrix構造体の要素を入れ替える
transpose()関数を実装せよ - 最初の実装はこんなかんじ
#[derive(Debug)]
struct Matrix(f32, f32, f32, f32);
fn transpose(matrix: Matrix) -> Matrix {
Matrix(matrix.0, matrix.2, matrix.1, matrix.3)
}
let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
println!("Matrix:\n{}", matrix);
// Matrix:
// ( 1.1 1.2 )
// ( 2.1 2.2 )
println!("Transpose:\n{}", transpose(matrix));
// Transpose:
// ( 1.1 2.1 )
// ( 1.2 2.2 )
- これだけだと、次のようにtrasnposeを呼び出した後の変数matrixを再利用できなくなってしまう
let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
println!("Matrix:\n{}", matrix);
println!("Transpose:\n{}", transpose(matrix));
println!("Matrix Again:\n{}", matrix);
// 以下のコンパイルエラー
error[E0382]: borrow of moved value: `matrix`
--> src/main.rs:79:35
|
73 | let matrix = Matrix(1.1, 1.2, 2.1, 2.2);
| ------ move occurs because `matrix` has type `Matrix`, which does not implement the `Copy` trait
...
78 | println!("Transpose:\n{}", transpose(matrix));
| ------ value moved here
79 | println!("Matrix Again:\n{}", matrix);
| ^^^^^^ value borrowed here after move
- rustにはオブジェクトの所有権があり、他の関数に渡してしまうとその後利用できなくなる
- 解決策は以下のいずれか
- Matrix構造体に
#[derive(Debug, Copy, Clone)]としてCopyトレイトとCloneトレイトを追加する - transpose関数の引数で参照を渡すようにする
fn transpose(matrix: &Matrix) -> Matrix {
Matrix(matrix.0, matrix.2, matrix.1, matrix.3)
}
println!("Matrix:\n{}", matrix);
println!("Transpose:\n{}", transpose(&matrix));
println!("Matrix Again:\n{}", matrix);
// 問題なく実行できる
[まとめ]
モブプログラミングスタイルでRust dojoを開催した。
ついに所有権の話がでてきた...!気をつけねば。
今週のプルリクエストはこちら。