Ich versuche, eine Enumeration zu erstellen, die Null, einen oder viele Werte enthalten kann (irgendwie klassisch) und mit denen ich durch eine einzige push(new_value:T)
-Methode interagieren würde. Es könnte entweder None
Wert (leer), One
Wert oder Many
Wert (im Grunde ein Vektor/Scheibe) haben.Kompilieren einer OneOrMany-Enumeration, die das Einfügen von Werten ermöglicht
Ich versuche, einen Wrapper für einen flexiblen Typ zu erstellen, der entweder ein einzelner Wert oder ein Vektor sein kann. Hier
ist das, was ich geschrieben habe, aber das kann ich nicht kompilieren
enum NoneOneOrMany<T> {
None,
One(T),
Many(Vec<T>),
}
struct FormValues<T> {
value: NoneOneOrMany<T>,
}
impl<T> FormValues<T> {
pub fn new() -> FormValues<T> {
FormValues { value: NoneOneOrMany::None }
}
pub fn push(&mut self, new_value: T) {
match self.value {
NoneOneOrMany::None => self.value = NoneOneOrMany::One(new_value),
NoneOneOrMany::One(existing_value) => {
let mut vec = Vec::<T>::new();
vec.push(existing_value);
vec.push(new_value);
self.value = NoneOneOrMany::Many(vec);
}
NoneOneOrMany::Many(ref mut vec) => {
vec.push(new_value);
}
}
}
}
die Fehler:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:17:15
|
17 | match self.value {
| ^^^^ cannot move out of borrowed content
18 | NoneOneOrMany::None => self.value = NoneOneOrMany::One(new_value),
19 | NoneOneOrMany::One(existing_value) => {
| -------------- hint: to prevent move, use `ref existing_value` or `ref mut existing_value`
Meine Gesamt Absicht war dann in der Lage sein, so etwas zu tun:
fn print_form_value<T: Debug>(x: FormValues<T>) {
match x.value {
NoneOneOrMany::None => println!("Empty"),
NoneOneOrMany::One(val) => println!("Holds one value => {:?}", val),
NoneOneOrMany::Many(vec) => println!("Holds several values => {:?}", vec),
}
}
fn test_oneOrMany() {
let mut x = FormValues::<u32>::new();
x.push(1);
x.push(2);
let mut y = FormValues::<u32>::new();
y.push(3);
let mut z = FormValues::<u32>::new();
print_form_value(x);
print_form_value(y);
print_form_value(z);
}
Es ist wahrscheinlich eine alberne klassische Kreditfrage, aber ich habe gerade begonnen, Rust zu verwenden. Gibt es eine Möglichkeit, move
existing_value
von ihm ist Option
in einem Vektor zu besitzen, ohne es zu klonen?
vielen dank @kennytm es tatsächlich gelöst! Aus Neugier, warum sagst du, dass 'SmallVec <[T;1]>' die Verschiebung verhindern würde (ich vermute, du beziehst dich auf 'let old_value = replace (& mut self.value, NoneOneOrMany :: None); ')? – Boris
@Boris Wenn 'self.value'' One (t) 'war, gäbe es zwei Züge des' t': zuerst von 'self.value' nach' old_value', zweitens von 'old_value' zum Vektor. Mit 'SmallVec' würde es nur eine Bewegung direkt vom Stapel geben' [T; 1] 'zum Haufen vec. Für 'T == u32' ist das natürlich keine große Sache, es ist nur ein Problem, wenn' T == SomeHugeStruct'. – kennytm