能否创建一个在行为上像 &mut 的包装器来封装 &mut?

4
以下代码无法编译,因为MutRef不是Copy。它不能被复制,因为&'a mut i32不是Copy。是否有任何方法使MutRef具有类似于&'a mut i32的语义?
这样做的动机是将大量的函数参数打包到一个结构体中,以便可以将它们作为一组传递,而不需要单独传递。
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
相关Reddit帖子 - SCappella
1个回答

3

编号。

这个功能的名称是“隐式重新借用”,它发生在您传递一个&mut引用,而编译器期望一个可能具有不同生命周期的&mut引用。当实际类型和预期类型都是&mut引用时,编译器才会隐式重新借用。它无法处理通用参数或包含&mut引用的结构体。在当前的Rust中,没有办法创建一个可以隐式重新借用的自定义类型。关于这个限制有一个未解决的问题,该问题始于2015年,但迄今为止没有人提出任何解决方法。

您始终可以实现自己的方法来显式重新借用:

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
}

参见


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接