ржавчина говорит черту не подразумевается - PullRequest
0 голосов
/ 20 января 2020

У меня есть перечисление:

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

И оно используется в Vec, который используется в HashMap:

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

, и я реализовал From черта для него для i32 (и других трех типов):

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(),
        }
    }
}

Можно ли создать функцию, которая может делать то же самое, но для возврата значения?

1 Ответ

4 голосов
/ 20 января 2020

Ошибка говорит о том, что From<EventValue> не реализовано для i32, а не From<i32> не реализовано для EventValue. С полностью определенными именами читать немного сложнее, но вот что

предел черты i32: std::convert::From<prelude::game::entity::components::event_stream::EventValue> не удовлетворен

говорит.

Проблема в том, что вы идете в неправильном направлении. Вы реализовали преобразование i32 -> EventValue, но не EventValue -> i32, что и пытается сделать ваш пример кода.

Возможно, вы захотите сопоставить вместо значения и обрабатывают не только случай Numeric, но также случаи Bool и Text.

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.

...