rust 说 trait From<i32> 没有实现

rust says trait From<i32> isn't implimented

我有一个枚举:

#[derive(PartialEq, Debug)]
pub enum EventValue {
    Numeric(i32),
    Bool(bool),
    Text(String),
}

它用在 Vec 中,用在 HashMap 中:

type Events = Vec<Event>;
pub type Stream = HashMap<String, Events>;

我已经为 i32(和其他三种类型)实现了 From 特性:

impl From<i32> for EventValue {
    fn from(v: i32) -> Self {
        EventValue::Numeric(v)
    }
}

impl From<String> for EventValue {
    fn from(v: String) -> Self {
        EventValue::Text(v)
    }
}

impl From<bool> for EventValue {
    fn from(v: bool) -> Self {
        EventValue::Bool(v)
    }
}

但是当我尝试在函数中使用它时:

let motions = event_stream.get_channel("motions"); // << return a Vec
for motion in motions.drain(0..) {
    let amount: i32 = motion.value.into(); // <-- here is where I get the error
    // .. do somthing with amount
}

我收到这个错误:

the trait bound `i32: std::convert::From<prelude::game::entity::components::event_stream::EventValue>` is not satisfied
  --> src/game/system/entity/movement.rs:17:48
   |
17 |                 let amount: i32 = motion.value.into();
   |                                                ^^^^ the trait `std::convert::From<prelude::game::entity::components::event_stream::EventValue>` is not implemented for `i32`
   |
   = help: the following implementations were found:
             <i32 as std::convert::From<bool>>
             <i32 as std::convert::From<i16>>
             <i32 as std::convert::From<i8>>
             <i32 as std::convert::From<std::num::NonZeroI32>>
           and 2 others
   = note: required because of the requirements on the impl of `std::convert::Into<i32>` for `prelude::game::entity::components::event_stream::EventValue`

我错过了什么?

奖金:

如果您像这样实现 From,就可以构建一个自动转换传入值的函数:


impl Event {
    pub fn new<V: Into<EventValue>>(message: String, value: V) -> Event {
        Self {
            message: message,
            value: value.into(),
        }
    }
}

是否可以创建一个可以做同样事情但返回值的函数?

错误说 From<EventValue> 没有为 i32 实现,而不是 From<i32> 没有为 EventValue 实现。使用完全限定名称,阅读起来有点困难,但就是这样

the trait bound i32: std::convert::From<prelude::game::entity::components::event_stream::EventValue> is not satisfied

在说。

问题是你走错了方向。您已经实现了转换 i32 -> EventValue,但没有实现 EventValue -> i32,这是您的示例代码正在尝试执行的操作。

您可能想要匹配值,不仅要处理 Numeric 情况,还要处理 BoolText 情况。

let motions = event_stream.get_channel("motions"); // << return a Vec
for motion in motions.drain(0..) {
    match motion.value {
        Numeric(value) => {// handle `Numeric` case},
        Bool(value) => {// handle `Bool` case},
        Text(text) => {// handle `Text` case},
    }
}

motion.value 可能是这三种变体中的任何一种,因此您不能假设它总是可以转换为 i32.