1

Here what I want to achieve:

trait Foo {
    fn readonly(&self) -> i32;
    fn modify(&mut self, val: i32);
}

struct FooWrapper<'a> {
    foo: &'a Foo,
}

impl<'a> FooWrapper<'a> {
    fn readonly(&self) -> i32 {
        self.foo.readonly()
    }

    fn modify(&mut self, val: i32) {
        self.foo.modify(val);//!!!
    }
}

As input I got &Foo and &mut Foo, like: fn func(a: &Foo, b: &mut Foo).

I want then wrap them inside FooWraper, and use it's methods to work with Foo.

But as you see compiler not allow code marked with //!!!.

Any way to fix this without code duplication like:

struct FooWrapper<'a> {
    foo: &'a Foo,
}
struct FooWrapperMut<'a> {
    foo: &'a mut Foo,
}
impl<'a> FooWrapper<'a>..
impl<'a> FooWrapperMut<'a>..

?

1
  • But as you see compiler not allow code — you need to include the complete compiler error. It is not acceptable to simply state that an error occurs. Commented Jun 9, 2017 at 12:43

1 Answer 1

2

Just make foo a mutable reference. Then it can be borrowed either mutably or immutably.

struct FooWrapper<'a> {
    foo: &'a mut Foo,
}

A &mut T reference can always be coerced to a &T.

If you wanted to provide minimal functionality for an immutable reference and some additional methods if you able to get a mutable reference, you could maybe split it out with type parameter:

trait Foo {
    fn readonly(&self) -> i32;
    fn modify(&mut self, val: i32);
}

struct FooWrapper<T> {
    foo: T,
}

impl <'a> FooWrapper<&'a Foo> {
    fn readonly(&self) -> i32 {
        self.foo.readonly()
    }
}

impl <'a> FooWrapper<&'a mut Foo> {
    fn modify(&mut self, val: i32) {
        self.foo.modify(val); //
    }
}

Now you can supply the type parameter to be either &mut Foo or just &Foo, depending on what you have.

Sign up to request clarification or add additional context in comments.

2 Comments

"Just make foo a mutable reference" I cann't, if I get &Foo as input how can I construct &mut Foo from it? See func as example.
You probably need to include more code in order to explain your problem, and to show that it is different from the duplicate (if it is).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.