ich diese Schnipsel haben, die nicht die borrow Prüfung nicht besteht:Kann nicht als wandelbar mehr als einmal in einer Zeit, in einem Code ausleihen - kann aber in einem anderen sehr ähnlich
use std::collections::HashMap;
enum Error {
FunctionNotFound
}
#[derive(Copy, Clone)]
struct Function<'a> {
name: &'a str,
code: &'a [u32]
}
struct Context<'a> {
program: HashMap<&'a str, Function<'a>>,
call_stack: Vec<Function<'a>>,
}
impl<'a> Context<'a> {
fn get_function(&'a mut self, fun_name: &'a str) -> Result<Function<'a>, Error> {
self.program.get(fun_name).map(|f| *f).ok_or(Error::FunctionNotFound)
}
fn call(&'a mut self, fun_name: &'a str) -> Result<(), Error> {
let fun = try!(self.get_function(fun_name));
self.call_stack.push(fun);
Ok(())
}
}
fn main() {
}
Mein Bauchgefühl ist, dass die Problem ist mit der Tatsache verbunden, dass HashMap
entweder None
oder eine Referenz des Wertes innerhalb der Datenstruktur zurückgibt. Aber ich will das nicht: meine Absicht ist, dass self.get_function
entweder eine Byte-Kopie des gespeicherten Wertes oder einen Fehler zurückgeben sollte (deshalb setze ich .map(|f| *f)
, und Function
ist Copy
).
Das Ändern von &'a mut self
zu etwas anderem hilft nicht.
jedoch folgende Schnipsel, ähnlich im Geiste, akzeptiert wird:
#[derive(Debug)]
enum Error {
StackUnderflow
}
struct Context {
stack: Vec<u32>
}
impl Context {
fn pop(&mut self) -> Result<u32, Error> {
self.stack.pop().ok_or(Error::StackUnderflow)
}
fn add(&mut self) -> Result<(), Error> {
let a = try!(self.pop());
let b = try!(self.pop());
self.stack.push(a + b);
Ok(())
}
}
fn main() {
let mut a = Context { stack: vec![1, 2] };
a.add().unwrap();
println!("{:?}", a.stack);
}
So, jetzt ich bin verwirrt. Was ist das Problem mit dem ersten Snippet? (Und warum passiert es nicht in der Sekunde?)
Die Schnipsel sind Teil eines größeren Codes. Um mehr Kontext bereitzustellen, zeigt this auf dem Rust Playground ein vollständigeres Beispiel mit dem fehlerhaften Code und this zeigt eine frühere Version ohne HashMap, die den Border-Checker übergibt und normal ausgeführt wird.
Ich glaube nicht, 'fun_name' sollte keine Lebensdauer haben. – o11c
Ihr zweites Snippet hat überhaupt keine Lebensdauern, so dass es sich nicht wirklich für "ähnlich" qualifiziert –