Реализовать From с несколькими параметрами типа - PullRequest
0 голосов
/ 27 мая 2020

Я играл с шаблоном дизайна посетителей в Rust. У моего первоначального посетителя не было параметра типа, поэтому я смог сделать что-то вроде этого:

impl<T> From<T> for Box<dyn VisitorElement>
where
    T: VisitorElement + 'static,
{
    fn from(elem: T) -> Box<dyn VisitorElement> {
        Box::new(elem)
    }
}

Поскольку мой посетитель был просто калькулятором f32, я хотел сделать его более универсальным c путем замены f32 параметром типа. После передачи повсюду правильного параметра типа моя реализация From не будет работать. Вот полный пример ( игровая площадка ):

/*
 * Visitor traits
 */
trait Visitor<T> {
    fn visit_literal(&mut self, literal: &Literal<T>);
}

trait VisitorElement<T> {
    fn accept(&self, visitor: &mut dyn Visitor<T>);
}
/*
 * Literal value
 */
struct Literal<T> {
    value: T,
}
impl<T> Literal<T> {
    fn new(value: T) -> Self {
        Self { value: value }
    }
}
impl<T> VisitorElement<T> for Literal<T> {
    fn accept(&self, visitor: &mut dyn Visitor<T>) {
        visitor.visit_literal(self)
    }
}

impl<K, T> From<K> for Box<dyn VisitorElement<T>>
where
    K: VisitorElement<T> + 'static,
{
    fn from(elem: K) -> Box<dyn VisitorElement<T>> {
        Box::new(elem)
    }
}

fn main() {
    let element = Literal::new(0.1);
    let boxed: Box<dyn VisitorElement<_>> = element.into();
}
error[E0119]: conflicting implementations of trait `std::convert::From<std::boxed::Box<(dyn VisitorElement<_> + 'static)>>` for type `std::boxed::Box<(dyn VisitorElement<_> + 'static)>`:
  --> src/main.rs:28:1
   |
28 | / impl<K, T> From<K> for Box<dyn VisitorElement<T>>
29 | | where
30 | |     K: VisitorElement<T> + 'static,
31 | | {
...  |
34 | |     }
35 | | }
   | |_^
   |
   = note: conflicting implementation in crate `core`:
           - impl<T> std::convert::From<T> for T;
   = note: downstream crates may implement trait `VisitorElement<_>` for type `std::boxed::Box<(dyn VisitorElement<_> + 'static)>`

Моя цель состояла в том, чтобы разрешить автоматическую сортировку динамических типов c, чтобы сделать ввод кода менее подробным.

From Как возникает конфликтная реализация `From` при использовании типа generi c? , я вижу, что тип S может привести к преобразованию трейта в себя, но в моем если тип K ограничен VisitorElement, но я все равно получаю конфликт с Box<dyn VisitorElement<_> + 'static>.

Есть ли причина, по которой ограничение на K: VisitorElement<T> + 'static позволяет Box<dyn VisitorElement<T> + 'static> самому себе но K: VisitorElement<f32> не делает?

Насколько я понимаю, тип K не может быть Box, потому что Box не реализует VisitorElement<T>, поэтому я никогда не должен a Box как K.

Если проблема была вызвана автоматической реализацией Into ... Я бы использовал From> для Literal<_>, затем Literal<_> в Box<dyn VisitorElement<_>, но это верно для любого типа. В моем случае это не делается явно, если только Box не является специальным типом, который реализует ту же черту, что и его содержимое?

...