Есть ли способ реализовать черту Add для любого типа, ограниченного чертой? - PullRequest
0 голосов
/ 24 июня 2018

Я читаю в разделе «Расширенные черты» книги Rust , где есть пример добавления двух не совпадающих типов:

use std::ops::Add;

struct Millimeters(u32);
struct Meters(u32);

impl Add<Meters> for Millimeters {
    type Output = Millimeters;

    fn add(self, other: Meters) -> Millimeters {
        Millimeters(self.0 + (other.0 * 1000))
    }
}

Предположим, что яимел черту, которую реализовали Millimeters и Meters, которая определяет, как превратить себя в метры (и при условии, что Millimeters и Meters реализуют это):

trait Length {
    fn to_meters(&self) -> Meters;
}

Есть ли способ написатьболее общая черта Add, которая выглядит примерно так (что недопустимо):

impl Add<T: Length> for Millimeters {
    type Output = Meters;

    fn add(&self, other: &T) -> Meters {
        let as_meters = other.to_meters();
        Meters((self.0 / 1000) + (as_meters.0))
    }
} 

1 Ответ

0 голосов
/ 24 июня 2018

Да, за исключением того, что вы необъяснимым образом поставили границу черты в неправильном месте и изменили сигнатуру функции на ссылки вместо значений.Исправление, которое заставляет его работать:

impl<T: Length> Add<T> for Millimeters {
    type Output = Meters;

    fn add(self, other: T) -> Meters {
        let as_meters = other.to_meters();
        Meters((self.0 / 1000) + (as_meters.0))
    }
}

Я бы использовал Into и предложение where, хотя:

impl<T> Add<T> for Millimeters
where
    T: Into<Meters>,
{
    type Output = Meters;

    fn add(self, other: T) -> Meters {
        let as_meters = other.into();
        Meters((self.0 / 1000) + (as_meters.0))
    }
}
...