Rubyなら簡単に動かせるコードがRustでは通らない
(エラーメッセージの読み方が間違っていたので修正しました。)
こんにちは。Rustでソフトウェアの開発を行なっています。
Rubyならラムダの中でさらに同インスタンスメソッドが呼び出し# (1)および代入# (2)ができます。
ruby
1# Rubyならこう書けば実現できるが… 2class Card 3 def run(assignor) 4 assignor[28] 5 end 6end 7 8class App 9 def assign(value) 10 @value = value # (2) 11 end 12 def setup 13 @value = 42 14 @card = Card.new 15 end 16 def update 17 @card.run( 18 ->(value) { self.assign(value) } # (1) 19 ) 20 puts @value # => 28と表示される 21 end 22end 23 24def main 25 app = App.new 26 app.setup 27 app.update 28end 29 30main
同様の動作をRustでも実現したい、しかし…
クロージャで同じように同オブジェクトのメソッドを呼び出そうと考えました。
しかしこれはうまくいきません。
rust
1// Rustではコンパイルエラーになる 2#[derive(Default)] 3pub struct Card; 4impl Card { 5 pub fn new() -> Self { 6 Self 7 } 8 pub fn run<F>(&self, mut assignor: F) 9 where 10 F: FnMut(i32), 11 { 12 assignor(28); 13 } 14} 15 16#[derive(Default)] 17struct App { 18 value: i32, 19 card: Card, 20} 21impl App { 22 fn assign(&mut self, value: i32) { 23 self.value = value; 24 } 25 pub fn setup(&mut self) { 26 self.value = 42; 27 self.card = Card::new(); 28 } 29 pub fn update(&mut self) { 30 self.card.run(|value| { 31 self.assign(value); 32 }); 33 println!("{}", self.value); 34 } 35} 36 37fn main() { 38 let mut app = App::default(); 39 app.setup(); 40 app.update(); 41}
エラーメッセージ抜粋
error[E0500]: closure requires unique access to `*self` but it is already borrowed --> src/main.rs:29:23 | 29 | self.card.run(|value| { | - --- ^^^^^^^ closure construction occurs here | | | | _________| first borrow later used by call | | 30 | | self.assign(value); | | ---- second borrow occurs due to use of `*self` in closure 31 | | }); | |__________- borrow occurs here
Rustでは二重に借用できないルールがあるようで、コンパイルできませんでした。
Rubyの書き方が非常に便利なため可能であればこれを何とかして実現したいです。
もし解決方法をご存じの方いらっしゃれば、恐縮ですが教えていただけないでしょうか。
よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/03/30 21:47
2022/03/30 23:10
2022/03/31 03:00