1
我試圖創建一個可容納零,一個或多個值(以某種古典),並與我會通過一個push(new_value:T)
方法互動一個枚舉。它可能有None
值(空),One
值或Many
值(基本上是矢量/切片)。不能編譯OneOrMany枚舉它允許值推到它
我試圖創建一個靈活的類型,可以是單個值或載體的包裝。
以下是我已經寫了,但我不能編譯
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);
}
}
}
}
錯誤:
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`
我的總的意圖是那麼能夠做這樣的事情:
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);
}
這可能是一個愚蠢的經典借貸的問題,但我剛開始使用生鏽。有沒有辦法將move
existing_value
從當前擁有Option
變成矢量而不必克隆它?
非常感謝@kennytm它確實解決了它!出於好奇,爲什麼你說'SmallVec <[T;1]>'將阻止移動(我猜你指的是'讓OLD_VALUE =替換(MUT self.value,NoneOneOrMany ::無);')? – Boris
@Boris當'self.value'是'一(噸)',就不會有在't'的兩個動作:首先從'self.value'到'old_value',第二從'old_value'到載體中。使用'SmallVec',只有一個直接從堆棧移動'[T; 1]'到堆vec。當然,對於'T == u32'來說,這真的不是什麼大問題,如果'T == SomeHugeStruct',這只是一個問題。 – kennytm