如何在特征函数中发送不同的结构?

时间:2019-10-27 12:51:30

标签: data-structures struct enums rust traits

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结构。因此,我唯一想到的选择是将其包装在enum中。但是还有更好的方法吗?

1 个答案:

答案 0 :(得分:3)

这看起来像是关联类型的用例:

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,反之亦然。