はじめに
#NO IMAGEThe Rust Programming Language 日本語版 - The Rust Programming Language 日本語版
を読んでいる
- とても眠い
お勉強
#メモ
#NO IMAGEクロージャ:環境をキャプチャする匿名関数 - The Rust Programming Language 日本語版
- 前回は構造体にcacheするしくみを実装してクロージャで呼び出すって話
- それの限界の話をされるらしい
しかし、現在のCacherの実装には、他の文脈で再利用することを困難にしてしまう問題が2つあります。
- さて、実装のしかたが悪いのかなんなのか
1番目の問題は、Cacherインスタンスが、常にvalueメソッドの引数argに対して同じ値になると想定していることです。
- ナニイッテルカワカリマセン
Cacherのこのテストは、失敗するでしょう
#[test]
fn call_with_different_values() {
let mut c = Cacher::new(|a| a);
let v1 = c.value(1);
let v2 = c.value(2);
assert_eq!(v2, 2);
}
- あーなるほどね
- すでにvalueがあるときはcacheしてある値しか返さない実装だったね
現在のCacher実装の2番目の問題は、引数の型にu32を一つ取り、u32を返すクロージャしか受け付けないことです。 例えば、文字列スライスを取り、usizeを返すクロージャの結果をキャッシュしたくなるかもしれません。 この問題を修正するには、Cacher機能の柔軟性を向上させるためによりジェネリックな引数を導入してみてください。
-
あーーここで作成しているCacherって全適応したいものだったのか
-
特定のものをcacheできればいいという思想だと思っていた
-
それなら納得できる
-
環境のキャプチャとかいうところきた
クロージャには、関数にはない追加の能力があります
- かっこいい
fn main() {
let x = 4;
let equal_to_x = |z| z == x;
let y = 4;
assert!(equal_to_x(y));
}
- おいいいいいいいいいいい、変な呪文唱えるなお前!!!!!
ここで、xはequal_to_xの引数でもないのに、 equal_to_xが定義されているのと同じスコープで定義されているx変数をequal_to_xクロージャは使用できています。
- たしかーに
fn main() {
let x = 4;
fn equal_to_x(z: i32) -> bool {
z == x
}
let y = 4;
assert!(equal_to_x(y));
}
- そうか、今まではこうやって書いていたか
- こっちの書き方では動かないらしい
クロージャは、3つの方法で環境から値をキャプチャでき、この方法は関数が引数を取れる3つの方法に直に対応します
所有権を奪う、可変で借用する、不変で借用するです。
- んんんんん?????
- なんかまずそうじゃん
並行性について語る第16章で、moveクロージャの例はもっと多く出てきます。
- まさに非同期の章でみた
fn main() {
let x = vec![1, 2, 3];
let equal_to_x = move |z| z == x;
// ここでは、xを使用できません: {:?}
println!("can't use x here: {:?}", x);
let y = vec![1, 2, 3];
assert!(equal_to_x(y));
}
- これなら分かりやすいな
Fnトレイトのどれかを指定するほとんどの場合、Fnから始めると、コンパイラがクロージャ本体内で起こっていることにより、 FnMutやFnOnceが必要な場合、教えてくれるでしょう。
- まあたしかに普通のよくよく考えれば普通の変数と同じでmoveするか借用するかだから変わらんか
- 借用って英語で例えたことないな、Borrowingらしい
一連の要素をイテレータで処理する
- イテレータに突入
イテレータパターンにより、一連の要素に順番に何らかの作業を行うことができます。
- そうだよね、そのイメージ
まとめ
#- クロージャをちゃんとやったことなかったのでまず、新概念でおもしろかった
- 具体的にここで使うとかはまだわからないけど、結構便利そう
- 急にクロージャ内に変数をmoveできるんだってびっくりした
次はイテレータ、やってみたかった
NO IMAGE一連の要素をイテレータで処理する - The Rust Programming Language 日本語版