質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

Q&A

解決済

1回答

775閲覧

Rustで所有権が移動してコンパイルできないのを解決したい

hasigyokuginkan

総合スコア28

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

0グッド

0クリップ

投稿2022/04/18 12:33

root.parent.child.update(&mut root); と書いてある部分で、おそらく update に root を渡しているせいで、所有権が移動(?)し、先頭の root がもう使えなくなっているようです。

これはどのように変更するとコンパイルできるようになるでしょうか?

各構造体はコピーせず、参照の状態で update に渡したいです。

該当のソースコード

Rust

1struct Root { 2 parent: Parent, 3 value: isize, 4} 5 6struct Parent { 7 child: Child, 8} 9 10struct Child { 11 value: isize, 12} 13 14impl Child { 15 fn update(&mut self, root: &mut Root) { 16 self.value += 1; 17 root.value += 1; 18 } 19} 20 21fn main() { 22 let mut root = Root { 23 value: 0, 24 parent: Parent { 25 child: Child { 26 value: 0, 27 }, 28 }, 29 }; 30 31 root.parent.child.update(&mut root); 32}

コンパイルエラーの内容

error[E0499]: cannot borrow `root.parent.child` as mutable more than once at a time --> examples/foo.rs:31:5 | 31 | root.parent.child.update(&mut root); | ^^^^^^^^^^^^^^^^^^------^---------^ | | | | | | | first mutable borrow occurs here | | first borrow later used by call | second mutable borrow occurs here error[E0499]: cannot borrow `root` as mutable more than once at a time --> examples/foo.rs:31:30 | 31 | root.parent.child.update(&mut root); | -------------------------^^^^^^^^^- | | | | | | | second mutable borrow occurs here | | first borrow later used by call | first mutable borrow occurs here For more information about this error, try `rustc --explain E0499`. error: could not compile `x` due to 2 previous errors

補足情報

rustc 1.58.1 (db9d1b20b 2022-01-20)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

状況によって解決方法は色々とあるとは思いますが、構造を変えずにというのを前提として置くなら RefCell が手っ取り早い方法だと思います。 これは借用規則を「実行時に」検査するかわりにコンパイル時の検査を緩和するものです。

コンパイル時の検査を緩める分の正しさをプログラマが保証しなければならない (けど人間は間違える) ので……可能なら避けるに越したことは無いんですが、 Rust の借用規則はなかなか厳しいので必要なこともそれなりにあります。

rust

1use std::cell::RefCell; 2 3struct Root { 4 parent: Parent, 5 value: RefCell<isize>, 6} 7 8struct Parent { 9 child: Child, 10} 11 12struct Child { 13 value: RefCell<isize>, 14} 15 16impl Child { 17 fn update(&self, root: &Root) { 18 *self.value.borrow_mut() += 1; 19 *root.value.borrow_mut() += 1; 20 } 21} 22 23fn main() { 24 let root = Root { 25 value: RefCell::new(0), 26 parent: Parent { 27 child: Child { 28 value: RefCell::new(0), 29 }, 30 }, 31 }; 32 33 root.parent.child.update(&root); 34}

投稿2022/04/18 16:39

SaitoAtsushi

総合スコア5444

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hasigyokuginkan

2022/04/18 23:00

大変勉強になります ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問