Определите две черты, такие, что функция должна существовать для декартового произведения двух наборов типов, которые ее реализуют.

Я хотел бы создать две черты, SaveSource а также SaveDestinationтак, что когда некоторые типы реализуют эти черты, функция:

fn save(a, b)

должны быть реализованы для всех a : SaveSource а также b : SaveDestination (и когда новый тип добавляется к SaveSource или же SaveDestination, он должен реализовать save функция для всех существующих SaveDestinationс или SaveSources.

Возможно ли что-то подобное? Если нет, могу ли я использовать что-нибудь, чтобы получить тот же результат?

1 ответ

Вы не можете заставить компилятор выдать ошибку, когда какая-то комбинация A а также B не реализует save, Но вы можете иметь общую функцию, которая требует, чтобы комбинация конкретных A а также B он получает инструменты save,

Для этого нам нужно обернуть save в черту и реализовать его на некоторый тип, который включает в себя как A а также B; самый простой вариант - это кортеж. (Однако согласованность может помешать, если черта и типы не все находятся в одном и том же ящике.)

trait Save {
    fn save(self);
}

struct Foo; // sample save source
struct Bar; // sample save destination

// save is defined for the combination of `Foo` and `Bar`
impl Save for (Foo, Bar) {
    fn save(self) {
        unimplemented!()
    }
}

// in order to call this, the type `(A, B)` must implement `Save`    
fn call_save<A, B>(a: A, b: B)
where
    (A, B): Save
{
    (a, b).save();
}

fn main() {
    // this call compiles because `impl Save for (Foo, Bar)` is present
    call_save(Foo, Bar);
}

Вы также можете сделать это для справок:

trait Save {
    fn save(self);
}

struct Foo;
struct Bar;

impl<'a, 'b> Save for (&'a Foo, &'b Bar) {
    fn save(self) {
        unimplemented!()
    }
}

fn call_save<'a, 'b, A, B>(a: &'a A, b: &'b B)
where
    (&'a A, &'b B): Save
{
    (a, b).save();
}

fn main() {
    call_save(&Foo, &Bar);
}
Другие вопросы по тегам