Как отправить различные структуры в функции черты? - PullRequest
2 голосов
/ 27 октября 2019
enum Property {
    Triangle(TriangleProperty),
    Square(SquareProperty),
}

struct Triangle {
    x: u8,
    y: Vec<u8>,
}

struct Square {
    x: u8,
    y: String,
}

struct TriangleProperty {
    a: u8,
    b: u8,
    c: u8,
}

struct SquareProperty {
    a: u8,
    b: u8,
    c: u8,
    d: u8,
}

trait Shape {
    fn do_magic(&self, p: Property) -> u64;
}

impl Shape for Triangle {
    fn do_magic(&self, p: Property) -> u64 {
        match (p) {
            Triangle(x) => { /* do something with x */ }
            _ => panic("this wont happen"),
        }
    }
}

impl Shape for Square {
    fn do_magic(&self, p: Property) -> u64 {
        match (p) {
            Square(x) => { /* do something with x */ }
            _ => panic("this wont happen"),
        }
    }
}

Как вы можете видеть, я звоню panic, что я не считаю хорошим способом справиться с этим.

Это просто пример, но у меня не может быть TriangleProperty внутри структуры Triangle. Потому что я использую TriangleProperty в качестве входных данных в функции do_magic, которая использует постоянную неизменную Triangle struct. Так что единственный вариант, который я могу придумать - это обернуть в enum. Но есть ли лучший способ сделать это?

1 Ответ

3 голосов
/ 27 октября 2019

Это похоже на вариант использования для связанного типа :

trait Shape {
    type Property;
    fn do_magic(&self, p: Self::Property) -> u64;
}

impl Shape for Triangle {
    type Property = TriangleProperty;
    fn do_magic(&self, p: Self::Property) -> u64 {
        /* do something with p */
    }
}

impl Shape for Square {
    type Property = SquareProperty;
    fn do_magic(&self, p: Self::Property) -> u64 {
        /* do something with p */
    }
}

Когда вы реализуете Shape, вы выбираете, какой тип будет Self::Property, и в пределах impl Вы можете использовать его как конкретный тип. Компилятор не позволит вам передать SquareProperty в Triangle::do_magic или наоборот.

...