回答編集履歴
3
`if self.cache.get(hash).is_none()` を `if !self.contains_key(hash)` に変更しました
answer
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
```rust
|
8
8
|
fn get_ref(&mut self, hash: &U256, tasks: &Tasks) -> Result<&Meta, String> {
|
9
9
|
// Metaの存在チェックをして、存在しないならcacheに追加する
|
10
|
-
if self.cache.
|
10
|
+
if !self.cache.contains_key(hash) {
|
11
11
|
match tasks.get_data(hash)? {
|
12
12
|
Some(data) => {
|
13
13
|
let meta = Meta::from(data);
|
2
ソースコードコメントを追加しました
answer
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
エラーメッセージによると、最初のmatchアーム`Some(meta) => Ok(meta)`で`self.cache`が所有する値への参照`&Meta`をmatch式の外に返しているのが原因のようです。`&Meta`が有効な間、つまり、`get_ref()`メソッドの外まで`self.cache`の不変借用が続くことになるので、たとえ`None`のアーム内であっても、その不変借用が有効になっています。
|
2
2
|
|
3
|
-
なぜこうなるのかというと、`get_ref()`から戻った後、`&Meta`が有効な間は`cache`マップの内容を変更できないようにするためです。もし変更を許すと、`&Meta`が指している`Meta`が`cache`マップから削除できてしまい、&Metaはダングリングポインタになってしまいます。
|
3
|
+
なぜこうなるのかというと、`get_ref()`から戻った後、`&Meta`が有効な間は`cache`マップの内容を変更できないようにするためです。もし変更を許すと、`&Meta`が指している`Meta`が`cache`マップから削除できてしまい、`&Meta`はダングリングポインタになってしまいます。
|
4
4
|
|
5
5
|
問題となっているのは`Ok(meta)`を返すところです。その部分が`self.cache.remove()`などと競合しないようにメソッドの最後に移せばエラーが解消します。
|
6
6
|
|
@@ -23,7 +23,8 @@
|
|
23
23
|
}
|
24
24
|
}
|
25
25
|
|
26
|
+
// cacheしておいたMetaを返す。これ以降は`&Mata`が有効な間は`self.cache`は
|
26
|
-
//
|
27
|
+
// 変更できなくなる
|
27
28
|
self.cache.get(hash).ok_or_else(|| "failed".to_owned())
|
28
29
|
}
|
29
30
|
```
|
1
説明を追加しました
answer
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
エラーメッセージによると、最初のmatchアーム`Some(meta) => Ok(meta)`で`self.cache`が所有する値への参照`&Meta`をmatch式の外に返しているのが原因のようです。`&Meta`が有効な間、つまり、`get_ref()`メソッドの外まで`self.cache`の不変借用が続くことになるので、たとえ`None`のアーム内であっても、その不変借用が有効になっています。
|
2
2
|
|
3
|
+
なぜこうなるのかというと、`get_ref()`から戻った後、`&Meta`が有効な間は`cache`マップの内容を変更できないようにするためです。もし変更を許すと、`&Meta`が指している`Meta`が`cache`マップから削除できてしまい、&Metaはダングリングポインタになってしまいます。
|
4
|
+
|
3
5
|
問題となっているのは`Ok(meta)`を返すところです。その部分が`self.cache.remove()`などと競合しないようにメソッドの最後に移せばエラーが解消します。
|
4
6
|
|
5
7
|
```rust
|