Suppose I have the following code:
enum Foo {
X { x: i32 },
Y { y: String },
}
// Change x value if foo is X, otherwise do nothing.
fn test(foo: Rc<RefCell<Foo>>) {
panic!("help!")
}
How do I implement test
? I know I can implement it by adding a new method to Foo
(either in impl Foo
or as a trait
) and using burrow_mut
, like so:
impl Foo {
pub fn go(&mut self) {
match self {
Foo::X { x } => *x = 3,
_ => (),
}
}
}
fn test(foo: Rc<RefCell<Foo>>) {
foo.borrow_mut().go()
}
I'm trying to come to grips with Rust's type system, so I was wondering if it's to implement something like this without a method, i.e., as a global function, or maybe even inline inside test
itself.
For example, this doesn't work:
fn go(foo: &mut Foo) {
match foo {
Foo::X { x } => *x = 3,
_ => (),
}
}
fn test(foo: Rc<RefCell<Foo>>) {
// mismatched types [E0308] expected `&mut Foo`, found `RefMut<Foo>`.
go(foo.borrow_mut())
}
Full error:
error[E0308]: mismatched types
--> src\main.rs:54:8
|
54 | go(foo.borrow_mut())
| -- ^^^^^^^^^^^^^^^^
| | |
| | expected `&mut Foo`, found struct `RefMut`
| | help: consider mutably borrowing here: `&mut foo.borrow_mut()`
| arguments to this function are incorrect
|
= note: expected mutable reference `&mut Foo`
found struct `RefMut<'_, Foo>`
EDIT Solution from duplicate
Both of these work:
go(&mut *foo.borrow_mut());
go(&mut foo.deref().borrow_mut());
let x: &mut Foo = &mut foo.deref().borrow_mut();
match x {
Foo::X {x} => *x = 3,
_ => (),
}