Is it possible to create a wrapper around an &mut that acts like an &mut

…衆ロ難τιáo~ 提交于 2020-06-23 04:14:28

问题


The following code fails to compile because MutRef is not Copy. It can not be made copy because &'a mut i32 is not Copy. Is there any way give MutRef similar semantics to &'a mut i32?

The motivation for this is being able to package up a large set of function parameters into a struct so that they can be passed as a group instead of needing to be passed individually.

struct MutRef<'a> {
    v: &'a mut i32
}

fn wrapper_use(s: MutRef) {
}

fn raw_use(s: &mut i32) {
}

fn raw_ref() {
    let mut s: i32 = 9;
    let q = &mut s;
    raw_use(q);
    raw_use(q);

}

fn wrapper() {
    let mut s: i32 = 9;
    let q = MutRef{ v: &mut s };
    wrapper_use(q);
    wrapper_use(q);
}

回答1:


No.

The name for this feature is "implicit reborrowing" and it happens when you pass a &mut reference where the compiler expects a &mut reference of a possibly different lifetime. The compiler only implicitly reborrows when the actual type and the expected type are both &mut references. It does not work with generic arguments or structs that contain &mut references. There is no way in current Rust to make a custom type that can be implicitly reborrowed.

However, you can implement your own method to explicitly reborrow:

impl<'a> MutRef<'a> {
    // equivalent to fn reborrow(&mut self) -> MutRef<'_>
    fn reborrow<'b>(&'b mut self) -> MutRef<'b> {
        MutRef {v: self.v}
    }
}

fn wrapper() {
    let mut s: i32 = 9;
    let mut q = MutRef{ v: &mut s };
    wrapper_use(q.reborrow());  // does not move q
    wrapper_use(q);             // moves q
}

See also

  • Why is the mutable reference not moved here?
  • Type inference and borrowing vs ownership transfer


来源:https://stackoverflow.com/questions/58567431/is-it-possible-to-create-a-wrapper-around-an-mut-that-acts-like-an-mut

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!