在可变引用上进行匹配时,如何在匹配臂中绑定变量?

She*_*ter 4 pattern-matching rust

我正在match使用结构,并且想使用火柴后卫。但是,该结构是可变的,并且匹配臂左侧的绑定变量似乎引起单独借用。然后,这将触发编译错误,因为在可变借贷未偿还的情况下,您不能再借(可变或不可变)。

struct A(u8);

impl A {
    fn is_awesome(&self) -> bool { true }
}

struct Container(A);

impl Container {
    fn update(&mut self) {}

    fn do_a_thing(&mut self) {
        match *self {
            Container(ref a) if a.is_awesome() => self.update(),
            _ => {},
        }
    }
}

fn main() {}
Run Code Online (Sandbox Code Playgroud)
struct A(u8);

impl A {
    fn is_awesome(&self) -> bool { true }
}

struct Container(A);

impl Container {
    fn update(&mut self) {}

    fn do_a_thing(&mut self) {
        match *self {
            Container(ref a) if a.is_awesome() => self.update(),
            _ => {},
        }
    }
}

fn main() {}
Run Code Online (Sandbox Code Playgroud)

我当前的解决方法是在比赛之前复制逻辑来计算比赛后卫,然后可以将布尔值用作比赛后卫。对于明显的代码重复问题,这并不令人满意:

fn do_a_thing(&mut self) {
    let awesome = match *self {
        Container(ref a) => a.is_awesome(),
    };

    match *self {
        Container(..) if awesome => self.update(),
        _ => {},
    }
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*gan 5

非词汇寿命已启用,原来的代码工作原样。

非词汇生命之前

以安全为名,Rust禁止使用各种类别的物品,即使它们的特定情况可能起作用。这是这种情况之一,您尝试做的尝试不可能,而且永远不可能。

您已经创建了对的内容的引用self,但是随后调用self.update()想要对进行可变引用self。一种语言可以有效地内联update,因此可以确定使引用保持活动状态是安全的,但是很容易证明基本概念并不总是能与Rust编译器使您免于遭受的这种不良示例结合使用:

struct A(u8);

struct Container(A);

impl Container {
    fn update(&mut self) {
        self.0 = A(0);
    }

    fn do_a_thing(&mut self) {
        let a = &self.0;
        let before = a.0;
        self.update();
        assert_eq!(before, a.0);
    }
}

fn main() {
    Container(A(1)).do_a_thing();
    // Panic: 1 != 0
}
Run Code Online (Sandbox Code Playgroud)

如果允许对此进行编译,则会引起恐慌,因为a尽管它的目标是不变的引用,但它的目标在您下面发生了变化,显然它不允许这样做。

C ++模板的快乐运气心态是尝试某些可能有效或无效的示例。他们很可能对函数内部进行深入的更改可能会破坏其用户,使他们无法再进行编译。Rust决定不走这条路,因此将每种方法都视为强大的隔离屏障。对函数主体的任何更改都不会导致方法外的代码停止编译。

self在上调用&mut self-requesting方法时,您对内部的任何内容均无任何可变的引用self