在 Rust 中借用和 return 可变引用的优雅方式

Elegant way to borrow and return a mutable reference in Rust

我正在尝试 return 对其进行一些操作后的可变引用。这最好用一段代码来解释:

#[derive(PartialEq)]
pub enum Value {
    Null,
    Array(Vec<Value>),
}

impl Value {
    pub fn new() -> Value {
        Value::Array(Vec::new())
    }

    pub fn push<'a, T> (&'a mut self, value: T) -> Option<&'a mut Value>
    where T:Into<Value> {
        let temp = match *self {
            Value::Array(ref mut vec) => {
                vec.push(value.into());
                true
            },
            _ => false,
        };
        if temp {
            Some(self)
        } else {
            None
        }
    }
}

#[test]
fn push_test() {
    let mut val = Value::new();
    val.push(Value::Null);
    assert!(val == Value::Array(vec![Value::Null]));
}

游戏版本为here。使用布尔值的解决方法是因为如果我从 match 块中 return Some(self) 我会多次借用。有没有不使用布尔值实现 push 函数的优雅方法?如果可以保留功能签名,那么它是一个奖励。谢谢!

The workaround with boolean values is because I would be borrowing multiple times if I return Some(self) from within the match block

另一种选择是临时替换 self,这样 v 就可以获得向量的所有权(避免借用)。将新项添加到 v 后,我们重构 self 值:

// the lifetime 'a can be omitted
pub fn push<T>(&mut self, value: T) -> Option<&mut Value>
    where T: Into<Value>
{
    // replace put Value::Null on self and return the old value
    match ::std::mem::replace(self, Value::Null) {
        Value::Array(mut v) => {
            v.push(value.into());
            *self = Value::Array(v);
            Some(self)
        },
        _ => None,
    }
}