質問編集履歴
1
矛盾としていたものが矛盾ではなかったので、そのように修正。
title
CHANGED
File without changes
|
body
CHANGED
@@ -11,46 +11,43 @@
|
|
11
11
|
これを次のように使うと、コメントしてある通りのエラーになります。
|
12
12
|
なお、コメントの通りライフタイムに名前を付けます。
|
13
13
|
|
14
|
+
**修正** 少し勘違いして間違ったことを書いていたので、編集させていただきました。これ以下は修正したものです。質問の趣旨は変わりません。また、その後の具体例があまり意味をなしていなかったので削除しました。
|
15
|
+
|
16
|
+
---
|
17
|
+
|
18
|
+
`x` の型を表すのに `decltype(x)` という表記を借りてくることにします。型同士の不等号はその型の生存期間の長さを表すものとします (サブタイピング的な意味ではありません) 。
|
19
|
+
|
20
|
+
|
14
21
|
```rust
|
15
22
|
// ブロック (3つ下の行から始まるもの) の外側のライフタイムを 'outer とします。
|
16
23
|
let mut x: i32 = 3;
|
17
24
|
let rx = &mut x;
|
18
25
|
{ // ブロック開始、この内部のライフタイムを 'inner とします。
|
19
26
|
let mut y = 4;
|
20
|
-
let ry = &
|
27
|
+
let ry = &mut y;
|
28
|
+
{ // さらにこの内部のライフタイムを適当に 'center とでもします。
|
29
|
+
let rry = foo(rx, ry);
|
21
30
|
|
31
|
+
// error: use of moved value: `rx`
|
22
|
-
|
32
|
+
// println!("{}", rx);
|
23
33
|
|
24
|
-
// error: use of moved value: `rx`
|
25
|
-
// println!("{}", rx);
|
26
|
-
|
27
|
-
|
34
|
+
// error: cannot borrow `ry` as immutable because `*ry` is also borrowed as mutable
|
28
|
-
|
35
|
+
// (と言って foo() の呼び出し箇所を指す)
|
29
|
-
|
36
|
+
// println!("{}", ry);
|
37
|
+
}
|
30
38
|
}
|
31
39
|
```
|
32
40
|
|
33
|
-
`x` の型を表すのに `decltype(x)` という表記を借りてくることにします。型同士の不等号はその型の生存期間の長さを表すものとします (サブタイピング的な意味ではありません) 。
|
34
|
-
|
35
41
|
1. エラーは `rx` がムーブされ、 `ry` が再借用されていることを表すので、 `T == decltype(rx)` かつ `T != decltype(ry)` となります。
|
36
|
-
2. `ry` の再借用がなされるからには、`T` の生存期間は `y` の生存期間 `'inner` と同じかそれより短い必要、つまり、`T <= 'inner` となる必要があるはずです。
|
42
|
+
2. `ry` の再借用がなされるからには、`T` の生存期間は `y` の生存期間 `'inner` と同じかそれより短い必要、つまり、`T <= 'inner` となる必要があるはずです。
|
37
|
-
3. `ry` を表示する `println!` が件のエラーを出すからには、 `println!` 実行時点で参照 `rry` が有効である必要、つまり `T >= '
|
43
|
+
3. `ry` を表示する `println!` が件のエラーを出すからには、 `println!` 実行時点で参照 `rry` が有効である必要、つまり `T >= 'center` となる必要があります。
|
38
44
|
|
39
|
-
これ
|
45
|
+
以上から `decltype(rx) == T == &'center mut i32` で、 `decltype(ry) == &'inner mut i32` ということになります。これはしかし不自然です。普通は `rx` の方が外で宣言されているので長く生き延びるはずですし、必要最低限の期間に絞られているとしたら `ry` もやはり絞られているべきと考えるからです。
|
40
46
|
|
41
|
-
|
47
|
+
**修正ここまで**
|
42
48
|
|
43
|
-
|
49
|
+
長くなりましたが、読んでいただきありがとうございます。よろしくお願いします。
|
44
50
|
|
45
|
-
|
51
|
+
---
|
46
52
|
|
47
|
-
```rust
|
48
|
-
let mut v = Vec::new();
|
49
|
-
v.push(1);
|
50
|
-
```
|
51
|
-
|
52
|
-
のとき、`v` の型が `let` の段階では完全には決まらないのと同様に、です。だとすると `foo()` の呼び出しの時点で `rx` の型が推論されるしかありません。しかしそれなら、そのときどのような推論が行われるにせよ、 `ry` についても同様の推論がされて `T == decltype(rx) == decltype(ry)` となるはずです。それなら `rx` も `ry` も両方ともムーブされるはずなので、妙です。
|
53
|
-
|
54
|
-
長くなりましたが、読んでいただきありがとうございます。よろしくお願いします。
|
55
|
-
|
56
53
|
ところで `foo()` に渡す順序を変えて `foo(ry, rx)` とすると、今度は `use of moved value: 'ry'` となりました。あまり考えず、第一引数に合わせて推論しているような気もします。
|