什么是* self的所有权在匹配表达式中用于生锈中的struct的impl

时间:2017-11-24 07:04:42

标签: rust

我正在使用here

中的示例
#[derive(Debug)]
enum List {
    Cons(i32, RefCell<Rc<List>>),
    Nil,
}

impl List {
    fn tail(&self) -> Option<&RefCell<Rc<List>>> {
        match *self {
            Cons(_, ref item) => Some(item),
            Nil => None,
        }
    }
}

鉴于函数签名为&selfself的引用类型为List*selfList实例本身。

但是我记得match也取得了它所匹配的对象的所有权,所以这不会给结构带来问​​题,因为List实例移动到match并且没有给出回来?

也不是&self不可变,为什么我们能够将self移到match

1 个答案:

答案 0 :(得分:3)

match 本身不会移动任何内容。移动,复制或借用发生在match的分支中。 例如:

let s = "test".to_string();
let a = s; // this is a move
// println!("{}", s); // ... so this is a "use after move" compilation error

但如果我们这样做:

match a { // this is allowed, a does not move anywhere
    // but in the branch...
    // this is an error: it would move a to res
    // res if res == "test".to_string() => "ok",
    // ^^^ moves value into pattern guard
    ref res if res == "test" => "ok", // with ref it's fine (we're
    // taking a by reference)
    _ => "ko",
}

playground

请注意,您可能确实遇到了match中的所有权问题,但这些问题通常是由于您在match关键字之后所做的事情。

例如,这失败了:

// let's break the string in two pieces
match a.split_off(2)
//    ^ cannot borrow mutably

但这是因为split_off需要&mut self,而不是结果上的match