2016-06-29 23 views
0

Ich versuche, eine änderbare Referenz nach einer Operation darauf zurückzugeben. Dies wird am besten durch ein Stück Code erklärt:Elegante Möglichkeit zum Ausleihen und Zurückgeben einer veränderbaren Referenz in Rust

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

Die Play-Version ist here. Die Problemumgehung mit booleschen Werten liegt darin, dass ich mehrere Male ausleihen würde, wenn ich Some(self) aus dem Block match zurückgebe. Gibt es eine elegante Möglichkeit, die push-Funktion ohne Verwendung boolescher Werte zu implementieren? Wenn es möglich ist, die Funktionssignatur zu behalten, dann ist das ein Bonus. Vielen Dank!

Antwort

1

Die Abhilfe mit Boolesche Werte ist, weil ich mehrere Male zu leihen würde, wenn ich Some(self) aus dem Spiel Block

Eine weitere Option zurückzukehren self zeitlich zu ersetzen, nehmen v kann so das Eigentum an der Vektor (das Ausleihen vermeiden). Nach dem Hinzufügen des neuen Artikels zu v, rekonstruieren wir den self Wert:

// 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, 
    } 
}