在 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,
}
}
我正在尝试 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,
}
}