1

I'm trying to return a mutable reference after doing some operation on it. This is best explained by a piece of code:

#[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]));
}

The play version is here. The workaround with boolean values is because I would be borrowing multiple times if I return Some(self) from within the match block. Is there an elegant way to implement the push function without using boolean values? If its possible to retain the function signature then its a bonus. Thank you!

4

1 回答 1

1

Some(self)布尔值的解决方法是因为如果我从匹配块中返回,我会多次借用

另一种选择是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,
    }
}
于 2016-06-29T22:00:18.660 回答