我需要处理来自包含不同数据类型的外部 rust 箱的枚举:

pub enum Variables {
    Float(f32),
    Double(f64)
}

我希望将其转换为我自己的通用数据 struct ,并将其包装在不同的 struct 中,以用元数据丰富它:

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MyWrapperVar<T> {
    num: i8,
    id: String,
    var: MyVar<T>,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MyVar<T> {
    name: String,
    value: T,
}

MyWrapperVar个实例将被序列化并发送给不同的消费者.为了便于序列化,我创建了多个new个函数:

impl MyVar<f32> {
    fn new(name: &str, value: f32) -> Self {
        Self {
            name: name.to_string(),
            value,
        }
    }
}

impl MyVar<f64> {
    fn new(name: &str, value: f64) -> Self {
        Self {
            name: name.to_string(),
            value,
        }
    }
}

impl<T> MyWrapperVar<T> {
    fn new(
        num: i8,
        id: &str,
        variable_name: &str,
        variable_value: T,
    ) -> MyWrapperVar<T> {
        Self {
            num,
            id: id.to_string(),
            var: MyVar::<T>::new(variable_name, variable_value),
        }
    }
}

我的印象是,我可以简单地匹配Variables,然后调用我的通用MyWrapperVar::new函数:

fn main() {
    let var1 = Variables::Float(0.1);
    match var1 {
        Variables::Float(v) => {
            let bla = MyWrapperVar::new(0, "bla", "var1", v);
        }
        Variables::Double(v) => {
            let bla = MyWrapperVar::new(0, "bla", "var1", v);
        }
    }
}

但是,这似乎不起作用,因为我收到以下错误:

error[E0599]: no function or associated item named `new` found for struct `MyVar<T>` in the current scope
  --> src/main.rs:42:30
   |
9  | pub struct MyVar<T> {
   | ------------------- function or associated item `new` not found for this struct
...
42 |             var: MyVar::<T>::new(variable_name, variable_value),
   |                              ^^^ function or associated item not found in `MyVar<T>`
   |
   = note: the function or associated item was found for
           - `MyVar<f32>`
           - `MyVar<f64>`

For more information about this error, try `rustc --explain E0599`.

请参见Rust Playground以获得MRE.

推荐答案

MyVar::new是为所有可能的T值定义的not,仅为f32f64这两个非常特定的值定义,但MyWrappedVar是为Tevery值实现的,包括&strString等值,因此您不能使用不受约束的T调用MyVar::new.解决方案是为相同的约束集定义MyWrappedVar::new作为MyVar::new,即仅为f32f64定义.

impl MyWrapperVar<f32> {
    fn new(
        num: i8,
        id: &str,
        variable_name: &str,
        variable_value: f32,
    ) -> MyWrapperVar<f32> {
        Self {
            num,
            id: id.to_string(),
            var: MyVar::<f32>::new(variable_name, variable_value),
        }
    }
}
impl MyWrapperVar<f64> {
    fn new(
        num: i8,
        id: &str,
        variable_name: &str,
        variable_value: f64,
    ) -> MyWrapperVar<f64> {
        Self {
            num,
            id: id.to_string(),
            var: MyVar::<f64>::new(variable_name, variable_value),
        }
    }
}

或者为every T实际实现MyVar::new:

impl<T> MyVar<T> {
    fn new(name: &str, value: T) -> Self {
        Self {
            name: name.to_string(),
            value,
        }
    }
}

Rust相关问答推荐

如何在 struct 中填充缓冲区并同时显示它?

关于Rust 中回归的逻辑

使用Clap时如何将String作为Into Str参数传递?

Tokio_Postgres行上未显示退回特性的生存期,且生命周期 不够长

定义只有一些字段可以缺省的 struct

如何设置activx websocket actorless的消息大小限制?

如何轮询 Pin>?

随机函数不返回随机值

从 rust 函数返回 &HashMap

Rust FFI 和 CUDA C 性能差异

需要一个有序向量来进行 struct 初始化

我可以禁用发布模式的开发依赖功能吗?

在1.5n次比较中找到整数向量中的最大和次大整数

在每个循环迭代中删除borrow

为什么 Rust 编译器在移动不可变值时执行复制?

没有通用参数的通用返回

为什么 match 语句对引用类型比函数参数更挑剔?

Iterator::collect如何进行转换?

为什么我不能为 Display+Debug 的泛型类型实现 std::error::Error 但有一个不是泛型参数的类型?

返回 &str 但不是 String 时,borrow 时间比预期长