Это упрощенный пример моего кода:
#[derive(Debug, Clone, Copy)]
enum Data<'a> {
I32(&'a [i32]),
F64(&'a [f64]),
}
impl<'a> From<&'a [i32]> for Data<'a> {
fn from(v: &'a [i32]) -> Data<'a> {
Data::I32(v)
}
}
impl<'a> From<&'a [f64]> for Data<'a> {
fn from(v: &'a [f64]) -> Data<'a> {
Data::F64(v)
}
}
#[derive(Debug, Clone, Copy)]
struct DataVar<'a> {
name: &'a str,
data: Data<'a>,
}
impl<'a> DataVar<'a> {
fn new<T>(name: &'a str, data: T) -> Self
where
T: Into<Data<'a>>,
{
Self {
name,
data: data.into(),
}
}
}
Прежде всего, учитывая, что мне нужно привести разные DataVar
s к одному и тому же вектору, и я хотел бы избежать использования объектов-чертКак вы думаете, моя реализация верна или у вас есть предложения по улучшению?
Теперь мой главный вопрос.Я могу определить новые DataVar
s, передающие срез, например, следующим образом:
let x = [1, 2, 3];
let xvar = DataVar::new("x", &x[..]);
Как я могу изменить свой конструктор, чтобы он работал не только со срезом, но также со ссылкой на массив иливектор?Например, я хотел бы, чтобы следующее работало также:
let x = [1, 2, 3];
let xvar = DataVar::new("x", &x);
РЕДАКТИРОВАТЬ:
Теперь я попытался реализовать тот же код, используя объект признака вместо перечисления, но результат дажехуже ... разве нет никакого решения для этого?
trait Data: std::fmt::Debug {}
impl Data for &[i32] {}
impl Data for &[f64] {}
#[derive(Debug, Clone, Copy)]
struct DataVar<'a> {
name: &'a str,
data: &'a dyn Data,
}
impl<'a> DataVar<'a> {
fn new<T>(name: &'a str, data: &'a T) -> Self
where
T: Data,
{
Self { name, data }
}
}
let x = [1, 2, 3];
let xvar = DataVar::new("x", &&x[..]);