首页 > 解决方案 > 与 Rc 匹配>

问题描述

考虑以下代码 - 可以编译和工作:

use std::rc::Rc;
use std::cell::RefCell;
use crate::Foo::{Something, Nothing};

enum Foo {
    Nothing,
    Something(i32),
}

fn main() {
    let wrapped = Rc::new(RefCell::new(Foo::Nothing));
    //....

    match *wrapped.borrow() {
        Something(x) => println!("{}", x),
        Nothing => println!("Nothing"),
    };        
}

现在我想匹配两个包装的值,而不仅仅是一个:

use std::rc::Rc;
use std::cell::RefCell;
use crate::Foo::{Something, Nothing};

enum Foo {
    Nothing,
    Something(i32),
}

fn main() {
    let wrapped1 = Rc::new(RefCell::new(Foo::Nothing));
    let wrapped2 = Rc::new(RefCell::new(Foo::Nothing));
    //....

    match (*wrapped1.borrow(), *wrapped2.borrow()) {
        (Something(x), Something(y)) => println!("{}, {}", x, y),
        _ => println!("Nothing"),
    };        
}

现在这将给出编译错误:

error[E0507]: cannot move out of dereference of `std::cell::Ref<'_, Foo>`
  --> src\main.rs:16:12
   |
16 |     match (*wrapped1.borrow(), *wrapped2.borrow()) {
   |            ^^^^^^^^^^^^^^^^^^ move occurs because value has type `Foo`, which does not implement the `Copy` trait

error[E0507]: cannot move out of dereference of `std::cell::Ref<'_, Foo>`
  --> src\main.rs:16:32
   |
16 |     match (*wrapped1.borrow(), *wrapped2.borrow()) {
   |                                ^^^^^^^^^^^^^^^^^^ move occurs because value has type `Foo`, which does not implement the `Copy` trait

我不太了解这两个示例的语义之间的根本区别。为什么会发生这种情况以及使第二个片段起作用的正确方法是什么?

标签: rustpattern-matchingownership

解决方案


    match (*wrapped1.borrow(), *wrapped2.borrow()) {

你当场在这里创建了一个元组。这些值被移动到新创建的元组中。这虽然有效:

use std::rc::Rc;
use std::cell::RefCell;
use crate::Foo::Something;

enum Foo {
    Nothing,
    Something(i32),
}

fn main() {
    let wrapped1 = Rc::new(RefCell::new(Foo::Nothing));
    let wrapped2 = Rc::new(RefCell::new(Foo::Nothing));

    match (&*wrapped1.borrow(), &*wrapped2.borrow()) {
        (Something(x), Something(y)) => println!("{}, {}", x, y),
        _ => println!("Nothing"),
    };        
}

推荐阅读