rust 如何在嵌套的泛型结构中调用泛型方法?

iyfjxgzm  于 2023-11-19  发布在  其他
关注(0)|答案(1)|浏览(114)

我需要处理来自外部Rust crate的枚举,它包含不同的数据类型:

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

字符串
我想将其转换为我自己的通用数据结构,并将其 Package 在一个不同的结构中,以使用元数据丰富它:

#[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。

6rqinv9w

6rqinv9w1#

MyVar::new不是针对T的所有可能值定义的,只针对两个非常具体的值,f32f64,但是MyWrappedVar针对T的 * 每个 * 值实现,包括诸如&strString,.,所以你不能用无约束的T调用MyVar::new。解决方案是为MyVar::new定义相同的约束集MyWrappedVar::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),
        }
    }
}

字符串
或者实际上为 everyT实现MyVar::new

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

相关问题