I have some code similar to this
enum Value<'a> {
Int(i64),
Flt(f64),
Vec(&'a [Value<'a>]),
}
and this lets me reuse some data; however, some times I want to accept heap-allocated data, so I would need something like this
enum Value {
Int(i64),
Flt(f64),
Vec(Box<Vec<Value>>),
}
but now I cannot accept slices! I know I could always have both of them in the same enum, like this
enum Value<'a> {
Int(i64),
Flt(f64),
VecSlice(&'a [Value<'a>]),
VecBox(Box<Vec<Value<'a>>>),
}
but this is very ugly.
Is there a way to have a struct or enum that accepts both slices and vectors in the same member/variant?
I know that for functions accepting &str and String we can just set the parameters to something like T: Into<String> but I have not figured out how to do something like this for vectors inside data types.
What you want is Cow:
enum Value<'a> {
Int (i64),
Flt (f64),
Vec (Cow<'a, [Value<'a>]>),
}
Unfortunately this doesn't work because of #38962. Until that issue is fixed, you may need to re-implement a specialized version of Cow for Value:
enum MyCow<'a> {
Borrowed (&'a[Value<'a>]),
Owned (Vec<Value<'a>>)
}
impl<'a> Deref for MyCow<'a> {
type Target = [Value<'a>];
fn deref (&self) -> &[Value<'a>] {
use crate::MyCow::{ Borrowed, Owned };
match *self {
Borrowed (borrowed) => borrowed,
Owned (ref owned) => &owned,
}
}
}
playground
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With