首页 > 解决方案 > 在 Rust 枚举/结构中同时接受 slice 和 Vec

问题描述

我有一些类似的代码

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>但我还没有弄清楚如何对数据类型中的向量执行类似的操作。

标签: vectorrustslice

解决方案


你想要的是Cow

enum Value<'a> {
    Int (i64),
    Flt (f64),
    Vec (Cow<'a, [Value<'a>]>),
}

不幸的是,由于#38962这不起作用。在解决该问题之前,您可能需要重新实现Cowfor的专用版本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,
        }
    }
}

操场


推荐阅读