如何解决错误 ‘already mutably borrowed: BorrowError’

huangapple go评论109阅读模式
英文:

how to solve the error 'already mutably borrowed: BorrowError'

问题

我不太擅长处理Rust中的RefCell,我想知道如何解决以下错误。

如果有人能回答我的问题,我将非常感激。

thread 'main' panicked at 'already mutably borrowed: BorrowError', src/main.rs:47:22

rust playground

英文:

I'm not very skilled with rust RefCell

and i want to know how to solve the following error.

I would be very grateful if someone could answer my question.

thread 'main' panicked at 'already mutably borrowed: BorrowError', src/main.rs:47:22

  1. use std::{
  2. cell::RefCell,
  3. rc::{Rc, Weak},
  4. };
  5. // parent
  6. struct P {
  7. i: Rc<RefCell<I>>,
  8. }
  9. impl P {
  10. fn new() -> P {
  11. let b = B {
  12. v: "b".to_string(),
  13. i: Weak::new(),
  14. };
  15. let c = C {
  16. v: "c".to_string(),
  17. i: Weak::new(),
  18. };
  19. let i = Rc::new(RefCell::new(I { b, c }));
  20. let ii = i.clone();
  21. let p = P { i };
  22. // init b.i
  23. let mut borrow_mut = RefCell::borrow_mut(&ii);
  24. let bb = &mut borrow_mut.b;
  25. bb.i = Rc::downgrade(&ii);
  26. // init c.i
  27. let cc = &mut borrow_mut.c;
  28. cc.i = Rc::downgrade(&ii);
  29. p
  30. }
  31. fn update_bv_cv(&self) {
  32. // update b.v
  33. let mut borrow_mut = RefCell::borrow_mut(&self.i);
  34. let b = &mut borrow_mut.b;
  35. b.v.push_str("=>p.update_bv_cv");
  36. // update c.v
  37. let c = &mut borrow_mut.c;
  38. c.v.push_str("=>p.update_bv_cv");
  39. // b update c.v
  40. let borrow = RefCell::borrow(&self.i);
  41. let b = &borrow.b;
  42. b.update_cv();
  43. }
  44. fn get_bv_cv(&self) -> (String, String) {
  45. let i = &self.i;
  46. let ii = i.borrow();
  47. let bv = ii.b.v.as_str();
  48. let cv = ii.c.v.as_str();
  49. (bv.into(), cv.into())
  50. }
  51. }
  52. // parent inner
  53. struct I {
  54. c: C,
  55. b: B,
  56. }
  57. // child
  58. struct C {
  59. i: Weak<RefCell<I>>,
  60. v: String,
  61. }
  62. // child
  63. struct B {
  64. i: Weak<RefCell<I>>,
  65. v: String,
  66. }
  67. impl B {
  68. fn update_cv(&self) {
  69. if let Some(i) = self.i.upgrade() {
  70. let mut ii = RefCell::borrow_mut(&i);
  71. ii.c.v.push_str("b.udpate_cv");
  72. }
  73. }
  74. }
  75. fn main() {
  76. let p = P::new();
  77. p.update_bv_cv();
  78. let (bv, cv) = p.get_bv_cv();
  79. println!("b.v: {bv}\nc.v: {cv}");
  80. }

rust playground

答案1

得分: 2

来自URLO的交叉帖子

以下是一个安全的解决方案:

  1. let i = {
  2. // b更新c.v
  3. let ref_i = RefCell::borrow(&self.i); // RefCell::<I>::borrow::<'r>(&'r self) -> Ref<'r, I>
  4. ref_i.b.i.clone() // 通过克隆Weak来丢弃 'r
  5. };
  6. update_cv_from_b(&i);
  7. fn update_cv_from_b(i: &Weak<RefCell<I>>) {
  8. if let Some(i) = i.upgrade() {
  9. let mut ii = RefCell::borrow_mut(&i);
  10. ii.c.v.push_str("b.udpate_cv");
  11. }
  12. }

playground

英文:

Came from a cross post in URLO

And here's a safe solution:

  1. let i = {
  2. // b update c.v
  3. let ref_i = RefCell::borrow(&amp;self.i); // RefCell::&lt;I&gt;::borrow::&lt;&#39;r&gt;(&amp;&#39;r self) -&gt; Ref&lt;&#39;r, I&gt;
  4. ref_i.b.i.clone() // throw away &#39;r via cloning Weak
  5. };
  6. update_cv_from_b(&amp;i);
  7. fn update_cv_from_b(i: &amp;Weak&lt;RefCell&lt;I&gt;&gt;) {
  8. if let Some(i) = i.upgrade() {
  9. let mut ii = RefCell::borrow_mut(&amp;i);
  10. ii.c.v.push_str(&quot;b.udpate_cv&quot;);
  11. }
  12. }

playground

huangapple
  • 本文由 发表于 2023年2月27日 08:28:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/75575891.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定