我有一些与此类似的代码
enum Value<'a> {
Int(i64),
Flt(f64),
Vec(&'a [Value<'a>]),
}
这使我可以重用一些数据;但是,有时候我想接受堆分配的数据,所以我需要像这样的东西
enum Value {
Int(i64),
Flt(f64),
Vec(Box<Vec<Value>>),
}
但是现在我不能接受切片!我知道我总是可以将它们都放在同一个枚举中,
enum Value<'a> {
Int(i64),
Flt(f64),
VecSlice(&'a [Value<'a>]),
VecBox(Box<Vec<Value<'a>>>),
}
但这很丑。
是否有一种方法可以使结构或枚举在同一成员/变量中同时接受切片和向量?
我知道,对于接受&str和String的函数,我们可以将参数设置为类似T: Into<String>
的方式,但是我还没有弄清楚如何对数据类型内部的矢量进行类似的处理。
答案 0 :(得分:2)
您想要的是Cow
:
enum Value<'a> {
Int (i64),
Flt (f64),
Vec (Cow<'a, [Value<'a>]>),
}
不幸的是,由于#38962,这不起作用。在解决该问题之前,您可能需要为Cow
重新实现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,
}
}
}
答案 1 :(得分:1)
我认为最接近您想要的是AsRef
特性。值得注意的是,Vec<T>
的{{1}},[T]
和[T;n]
实现了n <= 32
,还有其他一些事情(例如切片上的迭代器)也是如此。此外,AsRef<[T]>
实现了Box<T>
,但是您的AsRef<T>
场景在这里无法正常工作。不过,该枚举有点毛茸茸。类型说明不能完全起作用:
Box<Vec<T>>
因为您承诺一次只实例化一个enum Value<S>
where S: AsRef<[Value<S>]>
{
Int(i64),
Flt(f64),
Slice(S),
}
,并且要解决此问题,需要使用S
使其异构,这会变得很混乱。
如果您可以重构以使其在功能级别上起作用或在Box<dyn S>
之上创建更高级别的类型,则可以具有类似功能
Value
但是,使用此结构相当容易。在这种情况下,如果您有fn foo<S>(slice: S) where S: AsRef<[Value]> { }
,则调用Box<Vec<Value>>
不会有效,但由于foo(my_vec)
实现了{{1} }。
Box<[T]>