Как переопределить реализации свойств для определенных c типов в Rust? - PullRequest
0 голосов
/ 25 апреля 2020

В приведенном ниже примере реализация одной из этих характеристик будет работать. Компилятор не позволяет переопределить реализацию для определенных c типов.

Есть ли другой способ добиться этого?

trait Giver<T,U> {
    fn give_first(&self) -> T;
    fn give_second(&self) -> U;
}

struct Pair<T,U>(T,U);

impl<T,U> Giver<T,U> for Pair<T,U> where T:Clone, U:Clone {
    fn give_first(&self) -> T {
        (self.0).clone()
    }

    fn give_second(&self) -> U {
        (self.1).clone()
    }
}

//works 
impl Giver<i32, i32> for Pair<f32, f32> {
    fn give_first(&self) -> i32 {
        1
    }

    fn give_second(&self) -> i32 {
        2
    }
}


//error[E0119]: conflicting implementations of trait `Giver<f32, f32>` for type `Pair<f32, f32>`:
impl Giver<f32, f32> for Pair<f32, f32> {
    fn give_first(&self) -> f32 {
        1.0
    }

    fn give_second(&self) -> f32 {
        2.0
    }
}

1 Ответ

0 голосов
/ 25 апреля 2020
#![feature(specialization)]

trait Giver<T,U> {
    fn give_first(&self) -> T;
    fn give_second(&self) -> U;
}

#[derive(Debug)]
struct Pair<T,U>(T,U);

impl<T,U> Giver<T,U> for Pair<T,U> where T:Clone, U:Clone {
    default fn give_first(&self) -> T {
        (self.0).clone()
    }

    default fn give_second(&self) -> U {
        (self.1).clone()
    }
}

impl Giver<i32, i32> for Pair<f32, f32> {
    fn give_first(&self) -> i32 {
        1
    }

    fn give_second(&self) -> i32 {
        2
    }
}


impl Giver<f32, f32> for Pair<f32, f32> {
    fn give_first(&self) -> f32 {
        3.0
    }

    fn give_second(&self) -> f32 {
        4.0
    }
}

fn main() {
    {
        let p = Pair(0.0, 0.0);
        let first: i32 = p.give_first();
        let second: i32 = p.give_second();
        println!("{}, {}", first, second);  // 1, 2
    }

    {
        let p: Pair<f32, f32> = Pair(0.0, 0.0);
        let first: f32 = p.give_first();
        let second: f32 = p.give_second();
        println!("{}, {}", first, second);  // 3, 4
    }
}

ржавчина ночью, кажется, поддерживает это, если мы явно указываем ожидаемый тип возвращаемого значения. Я попробовал это с #![feature(specialization)]. Может быть более элегантное решение (подождет кого-то с большим знанием этого вопроса).

вывод: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=d618cd9b534a5ba49199a2efdcf607bd

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...