質問編集履歴

8

冒頭の見出しを修正

2022/04/04 10:37

投稿

akira_kano1101
akira_kano1101

スコア25

test CHANGED
File without changes
test CHANGED
@@ -1,4 +1,4 @@
1
- # Rubyなら簡単に動かせるコードRustでは通用ません。
1
+ # Rubyなら簡単に動かせるコードRustでも実現たい
2
2
 
3
3
  こんにちは。Rustでソフトウェアを開発しています。
4
4
 

7

日本語がおかしかったので修正

2022/04/03 22:10

投稿

akira_kano1101
akira_kano1101

スコア25

test CHANGED
File without changes
test CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  問題が二つあるので簡単に説明します。まずは記事中「問題のRustのコード」を確認していただきたいのですが、
6
6
 
7
- - `(*self.renderer)()`でクロージャ実行をしたいが共有参照`&mut`が関与しているのが原因なのか`F`のムーブが関与しているのが原因なのか、型サイズが不明なのが原因なのか、エラーメッセージを読んでもクロージャが呼べません。
7
+ - `(*self.renderer)()`でクロージャ実行をしたいが共有参照`&mut`が関与しているのが原因なのか`F`のムーブが関与しているのが原因なのか、型サイズが不明なのが原因なのか、クロージャが呼べません。
8
8
  - ライフタイムの関係でクロージャ内の一時変数がドロップされるのが理由なのか、構造体にそのクロージャを持たせたいのですが上手くできません。(こちらの方が特に問題)
9
9
 
10
10
  これらを解決したいです。

6

日本語がおかしかったので修正

2022/04/03 22:09

投稿

akira_kano1101
akira_kano1101

スコア25

test CHANGED
File without changes
test CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  問題が二つあるので簡単に説明します。まずは記事中「問題のRustのコード」を確認していただきたいのですが、
6
6
 
7
- - `(*self.renderer)()`でクロージャ実行をしたいが共有参照`&mut`が関与しているのが原因なのか`F`のムーブが関与しているのが原因なのか、型サイズが不明なのが原因なのか、エラーメッセージを読んでもクロージャが呼べない理由と呼べません。
7
+ - `(*self.renderer)()`でクロージャ実行をしたいが共有参照`&mut`が関与しているのが原因なのか`F`のムーブが関与しているのが原因なのか、型サイズが不明なのが原因なのか、エラーメッセージを読んでもクロージャが呼べません。
8
8
  - ライフタイムの関係でクロージャ内の一時変数がドロップされるのが理由なのか、構造体にそのクロージャを持たせたいのですが上手くできません。(こちらの方が特に問題)
9
9
 
10
10
  これらを解決したいです。

5

不要な文言の削除

2022/04/03 22:09

投稿

akira_kano1101
akira_kano1101

スコア25

test CHANGED
File without changes
test CHANGED
@@ -1,6 +1,6 @@
1
1
  # Rubyなら簡単に動かせるコードがRustでは通用しません。
2
2
 
3
- こんにちは。Rustでソフトウェアを開発しています。調べても見つからない問題が出てきたのでご存じの方のお力を借りたいと思い投稿します。
3
+ こんにちは。Rustでソフトウェアを開発しています。
4
4
 
5
5
  問題が二つあるので簡単に説明します。まずは記事中「問題のRustのコード」を確認していただきたいのですが、
6
6
 

4

タイトルなどわかりやすいよう修正

2022/04/03 22:08

投稿

akira_kano1101
akira_kano1101

スコア25

test CHANGED
@@ -1 +1 @@
1
- 【Rust】クロージャ内で作れた一時変数が解放されてまうめライフタイムの指定が必要かもしれな
1
+ 【Rust】クロージャ(ラムダ)に絡むコードがRubyな簡単に動くRustではコンパイルエラーになるのをしたい
test CHANGED
@@ -1,14 +1,17 @@
1
- # Rustで一時変数が絡だクロージャを構造体に保持したいが…
1
+ # Rubyなら簡単に動かせるコードがRustでは通用しませ
2
+
2
3
  こんにちは。Rustでソフトウェアを開発しています。調べても見つからない問題が出てきたのでご存じの方のお力を借りたいと思い投稿します。
3
4
 
4
- 問題が二つあるので簡単に説明します。
5
+ 問題が二つあるので簡単に説明します。まずは記事中「問題のRustのコード」を確認していただきたいのですが、
5
6
 
6
- - `(*self.renderer)()`でクロージャ実行をしたいが共有参照`&mut`が関与しているのが原因なのか`F`のムーブが関与しているのが原因なのか、型サイズが不明なのが原因なのか、エラーメッセージを読んでもクロージャが呼べない理由と呼ぶための解決方法がわかりません。
7
+ - `(*self.renderer)()`でクロージャ実行をしたいが共有参照`&mut`が関与しているのが原因なのか`F`のムーブが関与しているのが原因なのか、型サイズが不明なのが原因なのか、エラーメッセージを読んでもクロージャが呼べない理由と呼ません。
7
- - ライフタイムの関係でクロージャ内の一時変数がドロップされるのが理由なのか、構造体にそのクロージャを持たせたいのですが上手くできません。
8
+ - ライフタイムの関係でクロージャ内の一時変数がドロップされるのが理由なのか、構造体にそのクロージャを持たせたいのですが上手くできません。(こちらの方が特に問題)
9
+
10
+ これらを解決したいです。
8
11
 
9
12
  検証のため問題を再現した最小のRustのコードを以下に用意しました。
10
13
 
11
- 解決方法がわからないのでもしご存じの方いらっしゃれば教えていただけないでしょうか。
14
+ もしご存じの方いらっしゃれば教えていただけないでしょうか。
12
15
 
13
16
  (Rubyでは実行できることを確認したので追記しました。)
14
17
 

3

Rubyのコードと比較できるよう修正

2022/04/03 21:58

投稿

akira_kano1101
akira_kano1101

スコア25

test CHANGED
File without changes
test CHANGED
@@ -1,14 +1,72 @@
1
1
  # Rustで一時変数が絡んだクロージャを構造体に保持したいが…
2
2
  こんにちは。Rustでソフトウェアを開発しています。調べても見つからない問題が出てきたのでご存じの方のお力を借りたいと思い投稿します。
3
3
 
4
- 検証のため問題を再現した最小コードを下記の通り用意しました
4
+ 問題が二つあるで簡単に説明しま
5
5
 
6
+ - `(*self.renderer)()`でクロージャ実行をしたいが共有参照`&mut`が関与しているのが原因なのか`F`のムーブが関与しているのが原因なのか、型サイズが不明なのが原因なのか、エラーメッセージを読んでもクロージャが呼べない理由と呼ぶための解決方法がわかりません。
6
- ライフタイムの関係でクロージャ内の一時変数がドロップされ構造体にそのクロージャを持たせることができません。
7
+ - ライフタイムの関係でクロージャ内の一時変数がドロップされるのが理由なのか、構造体にそのクロージャを持たせたいのです上手くできません。
8
+
9
+ 検証のため問題を再現した最小のRustのコードを以下に用意しました。
7
10
 
8
11
  解決方法がわからないのでもしご存じの方いらっしゃれば教えていただけないでしょうか。
9
12
 
13
+ (Rubyでは実行できることを確認したので追記しました。)
14
+
15
+ ## 本題
16
+
17
+ ### 動作するRubyのコード
18
+ Rubyでなら同じ問題は起こりません。
19
+
20
+ ```ruby
21
+ class Card
22
+ def initialize(renderer)
23
+ @renderer = renderer
24
+ end
25
+ def render
26
+ @renderer[]
27
+ end
28
+ end
29
+
30
+ class Presenter
31
+ def get
32
+ "Message"
33
+ end
34
+ end
35
+
36
+ class App
37
+ def initialize
38
+ @presenter = Presenter.new
39
+ @card = Card.new(->() { "" })
40
+ end
41
+ def setup
42
+ @presenter = Presenter.new
43
+ @card = Card.new(->() { @presenter.get() })
44
+ end
45
+ def update
46
+ puts @card.render # => "Message"と表示される
47
+ end
48
+ end
49
+
50
+ def main
51
+ app = App.new
52
+ app.setup
53
+ app.update
54
+ end
55
+
56
+ main
57
+ ```
58
+
10
- ## 問題のコード(検証用)
59
+ ### 問題のRustのコード(検証用)
60
+ そしてこちらが問題です。
11
61
  ```rust
62
+ struct Presenter;
63
+
64
+ impl Presenter {
65
+ pub fn get(&self) -> String {
66
+ "Message".to_string()
67
+ }
68
+ }
69
+
12
70
  struct Card<'a, F>
13
71
  where
14
72
  F: ?Sized + FnOnce() -> String,
@@ -23,58 +81,73 @@
23
81
  pub fn new(renderer: &'a F) -> Self {
24
82
  Self { renderer: renderer }
25
83
  }
26
- }
27
-
28
- #[derive(Default)]
29
- struct Presenter;
30
-
31
- impl Presenter {
32
- pub fn get(&self) -> Option<String> {
84
+ pub fn render(&self) -> String {
33
- Some("Message".to_string())
85
+ (*self.renderer)() // コンパイルエラー
34
86
  }
35
87
  }
36
88
 
37
- #[derive(Default)]
38
89
  struct App<'a> {
39
- card: Option<Card<'a, dyn FnOnce() -> String>>,
40
90
  presenter: Presenter,
91
+ card: Card<'a, dyn FnOnce() -> String>,
41
92
  }
42
93
 
43
94
  impl<'a> App<'a> {
95
+ pub fn new() -> Self {
96
+ Self {
97
+ presenter: Presenter,
98
+ card: Card::new(&|| "".to_string()),
99
+ }
100
+ }
44
101
  pub fn setup(&mut self) {
45
- self.card = Some(Card::new(&|| self.presenter.get().unwrap()));
102
+ self.card = Card::new(&|| self.presenter.get()); // コンパイルエラー
103
+ }
104
+ pub fn update(&mut self) {
105
+ println!("{:?}", self.card.render());
46
106
  }
47
107
  }
48
108
 
49
109
  fn main() {
50
- let mut app = App::default();
110
+ let mut app = App::new();
51
111
  app.setup();
112
+ app.update();
52
113
  }
53
114
  ```
54
115
 
55
- ## エラーメッセージ抜粋
116
+ ### エラーメッセージ抜粋
56
117
  ```
118
+ error[E0161]: cannot move a value of type F: the size of F cannot be statically determined
119
+ --> src/main.rs:24:9
120
+ |
121
+ 24 | (*self.renderer)()
122
+ | ^^^^^^^^^^^^^^^^
123
+
124
+ error[E0507]: cannot move out of `*self.renderer` which is behind a shared reference
125
+ --> src/main.rs:24:9
126
+ |
127
+ 24 | (*self.renderer)()
128
+ | ^^^^^^^^^^^^^^^^ move occurs because `*self.renderer` has type `F`, which does not implement the `Copy` trait
129
+
57
130
  error: lifetime may not live long enough
58
- --> src/main.rs:34:36
131
+ --> src/main.rs:41:31
59
132
  |
60
- 33 | pub fn setup(&mut self) {
133
+ 40 | pub fn setup(&mut self) {
61
134
  | - let's call the lifetime of this reference `'1`
62
- 34 | self.card = Some(Card::new(&|| self.presenter.get().unwrap()));
135
+ 41 | self.card = Card::new(&|| self.presenter.get());
63
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static`
136
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static`
64
137
 
65
138
  error[E0716]: temporary value dropped while borrowed
66
- --> src/main.rs:34:37
139
+ --> src/main.rs:41:32
67
140
  |
68
- 32 | impl<'a> App<'a> {
141
+ 33 | impl<'a> App<'a> {
69
142
  | -- lifetime `'a` defined here
70
- 33 | pub fn setup(&mut self) {
143
+ ...
71
- 34 | self.card = Some(Card::new(&|| self.presenter.get().unwrap()));
144
+ 41 | self.card = Card::new(&|| self.presenter.get());
72
- | ----------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--
145
+ | -----------------------^^^^^^^^^^^^^^^^^^^^^^^-
73
- | | |
146
+ | | |
74
- | | creates a temporary which is freed while still in use
147
+ | | creates a temporary which is freed while still in use
75
148
  | assignment requires that borrow lasts for `'a`
76
- 35 | }
149
+ 42 | }
77
150
  | - temporary value is freed at the end of this statement
78
151
  ```
79
152
 
80
- 初歩的な内容かと思いますが、ご回答のほどよろしくお願いいたします。
153
+ ご回答のほどよろしくお願いいたします。

2

タイトル修正

2022/04/03 13:58

投稿

akira_kano1101
akira_kano1101

スコア25

test CHANGED
@@ -1 +1 @@
1
- 【Rust】クロージャ内で作られた一時変数が解放されてしまうためライフタイムの指定の方法ない
1
+ 【Rust】クロージャ内で作られた一時変数が解放されてしまうためライフタイムの指定が必要もしれない
test CHANGED
File without changes

1

タイトル修正

2022/04/03 13:57

投稿

akira_kano1101
akira_kano1101

スコア25

test CHANGED
@@ -1 +1 @@
1
- 【Rust】クロージャ内で作られた一時変数が解放されてしまうためライフタイムの指定が必要ようだが書き方がわからない
1
+ 【Rust】クロージャ内で作られた一時変数が解放されてしまうためライフタイムの指定の方がわからない
test CHANGED
@@ -1,5 +1,5 @@
1
1
  # Rustで一時変数が絡んだクロージャを構造体に保持したいが…
2
- こんにちは。Rustでソフトウェアを開発しています。調べても見つからない問題が出てきたので識者のお力を借りたいと思い投稿します。
2
+ こんにちは。Rustでソフトウェアを開発しています。調べても見つからない問題が出てきたのでご存じ方のお力を借りたいと思い投稿します。
3
3
 
4
4
  検証のため問題を再現した最小のコードを下記の通り用意しました。
5
5
 
@@ -78,5 +78,3 @@
78
78
  ```
79
79
 
80
80
  初歩的な内容かと思いますが、ご回答のほどよろしくお願いいたします。
81
-
82
-