回答編集履歴

4

注意書き

2021/09/25 17:03

投稿

退会済みユーザー
test CHANGED
@@ -48,15 +48,17 @@
48
48
 
49
49
  ```rust
50
50
 
51
- pub fn func<'a>(&'a mut self) -> Result<(), &'a str> {
51
+ // 疑似コードなのでコンパイルできません
52
52
 
53
- Element::set::<'b>(&'b mut self.field[0], 0)?;
53
+ pub fn func<'a>(&'a mut self) -> Result<(), &'a str> {
54
54
 
55
- Element::set::<'c>(&'c mut self.field[0], 1)?;
55
+ Element::set::<'b>(&'b mut self.field[0], 0)?;
56
56
 
57
- Ok(())
57
+ Element::set::<'c>(&'c mut self.field[0], 1)?;
58
58
 
59
+ Ok(())
60
+
59
- }
61
+ }
60
62
 
61
63
  ```
62
64
 
@@ -124,6 +126,10 @@
124
126
 
125
127
 
126
128
 
129
+ `'static`にできない場合は、おとなしく`String`を返した方が楽だと思います(特に初心者のうちは).
130
+
131
+
132
+
127
133
  > ?演算子を使わなければエラーが出ない
128
134
 
129
135
 

3

推敲

2021/09/25 17:03

投稿

退会済みユーザー
test CHANGED
@@ -2,29 +2,35 @@
2
2
 
3
3
 
4
4
 
5
- 詳細は [The Rust Programming Language 日本語版 10.3 ライフタイムで参照を検証する](https://doc.rust-jp.rs/book-ja/ch10-03-lifetime-syntax.html) の「ライフタイム省略」をご自身で読んで確認していただきたいですが、今回は、以下の文が非常に重要す.
5
+ 詳細は [The Rust Programming Language 日本語版 10.3 ライフタイムで参照を検証する](https://doc.rust-jp.rs/book-ja/ch10-03-lifetime-syntax.html) の「ライフタイム省略」をご自身で読んで確認していただきたいですが、重要な部分だけ引用します.
6
6
 
7
7
 
8
8
 
9
- > 3番目の規則は、数の入力ライフタイム引数があけれど、メソッドなのでそのうちの一つが&selfや&mut selfだったらselfのライフタイムが全出力ライフタイム引数に代入されるというものです。
9
+ > 最初の規則は、参照である各引は、独自のライフタイム引数を得というものです。換言すれば1引数関数は、1つのライフタイム引数を得るということです: fn foo<'a>(x: &'a i32); 2つ引数のある関数は、2つの個別のライフタイム引数を得ま: fn foo<'a, 'b>(x: &'a i32, y: &'b i32); 以下同様
10
10
 
11
11
 
12
12
 
13
+ > 2番目の規則は、1つだけ入力ライフタイム引数があるなら、そのライフタイムが全ての出力ライフタイム引数に代入されるというものです: fn foo<'a>(x: &'a i32) -> &'a i32。
14
+
15
+
16
+
17
+ > 3番目の規則は、複数の入力ライフタイム引数があるけれども、メソッドなのでそのうちの一つが&selfや&mut selfだったら、 selfのライフタイムが全出力ライフタイム引数に代入されるというものです。 この3番目の規則により、必要なシンボルの数が減るので、メソッドが遥かに読み書きしやすくなります。
18
+
19
+
20
+
13
- つまり、今回の例で言えば、以下の関数は、
21
+ 今回の例で言えば、`set`関数は、1番目の規則によって以下のようになり、
14
22
 
15
23
 
16
24
 
17
25
  ```rust
18
26
 
19
- pub fn set(&mut self, num: i32)-> Result<(), &str> {}
27
+ pub fn set<'a>(&'a mut self, num: i32)-> Result<(), &str> {}
20
28
 
21
29
  ```
22
30
 
23
31
 
24
32
 
25
- 以下のようなライフタイムを持った関数と同等だということです.
33
+ さらに2番目の規則によって、以下のようなライフタイムを持った関数だと解釈されます.
26
-
27
-
28
34
 
29
35
 
30
36
 
@@ -36,7 +42,7 @@
36
42
 
37
43
 
38
44
 
39
- それを踏まえた上で`func`の定義を見てみると、こちらも以下のよに解釈されます.
45
+ `func`関数も同様に考えてみましょ.一旦疑似コードで表してみます.
40
46
 
41
47
 
42
48
 
@@ -44,9 +50,9 @@
44
50
 
45
51
  pub fn func<'a>(&'a mut self) -> Result<(), &'a str> {
46
52
 
47
- self.field[0].set(0)?;
53
+ Element::set::<'b>(&'b mut self.field[0], 0)?;
48
54
 
49
- self.field[0].set(1)?;
55
+ Element::set::<'c>(&'c mut self.field[0], 1)?;
50
56
 
51
57
  Ok(())
52
58
 
@@ -56,33 +62,11 @@
56
62
 
57
63
 
58
64
 
59
- して、返り値のうちエラーの方の`&str`のライフタイムは、`'a`で共通のですか疑似コード的ば以下のようになります.
65
+ ここで、`&mut self`の制約からは、`'b`,`'c`は`'a`より決して長くならないことが言えます.逆に、`&str`の制約からは、`'b`,`'c`が`'a`より長くる必要があることが言えま.そしてこれらを合わせると`'a`=`'b`=`'c`となります.ししこれでは同じライフタイムを持った可変参照が同時に存在するので、借用規則に反しておりンパイルエラーになるというわす.
60
66
 
61
67
 
62
68
 
63
-
64
-
65
- ```rust
66
-
67
- pub fn func<'a>(&'a mut self) -> Result<(), &'a str> {
68
-
69
- Element::set::<'a>(&'a mut self.field[0], 0)?;
70
-
71
- Element::set::<'a>(&'a mut self.field[0], 1)?;
72
-
73
- Ok(())
74
-
75
- }
76
-
77
- ```
78
-
79
-
80
-
81
- こう見ると、同じライフタイムを持った可変参照が同時に存在するので、借用規則に反することがわかると思います.
82
-
83
-
84
-
85
- 根本的な原因は、ライフタイムパラメータおかしいことなので、今回であれば以下のようにライフタイムを`'static`にすれば、コンパイルエラーは解消します.
69
+ 根本的な原因は、返り値のライフタイムが不当に狭くなってことなので、今回であれば以下のようにライフタイムを`'static`にすれば、コンパイルエラーは解消します.
86
70
 
87
71
 
88
72
 
@@ -136,8 +120,6 @@
136
120
 
137
121
  }
138
122
 
139
-
140
-
141
123
  ```
142
124
 
143
125
 

2

引用箇所を明確に

2021/09/25 16:53

投稿

退会済みユーザー
test CHANGED
@@ -142,7 +142,7 @@
142
142
 
143
143
 
144
144
 
145
- > ?演算子を使わなければエラーが出ないので、?演算子を使うことで借用期間が延長されてしまっているのだと思います
145
+ > ?演算子を使わなければエラーが出ない
146
146
 
147
147
 
148
148
 

1

微修正

2021/09/25 16:32

投稿

退会済みユーザー
test CHANGED
@@ -82,7 +82,7 @@
82
82
 
83
83
 
84
84
 
85
- 根本的な原因は、ライフタイムパラメータがおかしいことなので、今回であれば以下のように`'static`にしてやればコンパイルエラーは解消するはずです
85
+ 根本的な原因は、ライフタイムパラメータがおかしいことなので、今回であれば以下のようにライフタイムを`'static`にればコンパイルエラーは解消します.
86
86
 
87
87
 
88
88
 
@@ -90,7 +90,53 @@
90
90
 
91
91
  ```rust
92
92
 
93
+ struct Element {
94
+
95
+ element: i32,
96
+
97
+ }
98
+
99
+ impl Element {
100
+
93
- pub fn set(&mut self, num: i32) -> Result<(),&'static str>
101
+ pub fn set(&mut self, num: i32) -> Result<(), &'static str> {
102
+
103
+ if num == 0 {
104
+
105
+ return Err("えらー");
106
+
107
+ }
108
+
109
+ self.element = num;
110
+
111
+ Ok(())
112
+
113
+ }
114
+
115
+ }
116
+
117
+
118
+
119
+ struct Field {
120
+
121
+ field: [Element; 10],
122
+
123
+ }
124
+
125
+ impl Field {
126
+
127
+ pub fn func(&mut self) -> Result<(), &'static str> {
128
+
129
+ self.field[0].set(1)?;
130
+
131
+ self.field[0].set(1)?;
132
+
133
+ Ok(())
134
+
135
+ }
136
+
137
+ }
138
+
139
+
94
140
 
95
141
  ```
96
142
 
@@ -100,4 +146,4 @@
100
146
 
101
147
 
102
148
 
103
- おそらくこれは誤解かと.
149
+ おそらくこれは勘違いじゃないと.