简单组织Rust特征的“多态”返回

时间:2016-12-27 20:53:01

标签: polymorphism rust traits

我有一个名为Frame的基本结构,对于一堆计算很有用:

pub struct Frame<T> {
    grid_val: Vec<T>,
    grid_space: Vec<[T; 2]>,
    calculated_result: Option<Vec<T>>
}

Frame可用于描述大多数基本计算,但有时会出现更复杂的问题,我需要添加更多几何信息。所以我为每个几何使用了合成:

pub struct Sphere<T> {
    grid: Frame<T>,
    radius: T
}

pub struct Hyperbola<T> {
    top_grid: Frame<T>,
    bottom_grid: Frame<T>,
    internal_angle: T
}

现在,我Algorithm的{​​{1}}工作实施了:

Sphere

这会填写pub trait Algorithm<T> { fn calculate_something(&self) -> Result<Sphere<T>, Error> } impl Algorithm<T> for Hyperbola { // do things with top_grid, bottom_grid, and internal_angle } impl Algorithm<T> for Sphere { // do things with grid and radius } 并返回新的calculated_result。它是以这种方式实现的,因为Sphere需要使用额外的几何信息来计算Algorithm - 在语义上,它更有意义,它是几何体上的一个实现,其结果恰好与一个实现相关联或更多calculated_result s。

我想为Frame实现相同的Algorithm。事实上,它非常接近相同,并且特征是相同的,但它返回Hyperbola是没有意义的。

我知道我可以添加另一个特征Sphere<T>并添加另一层构图,但这似乎过分了。我想我可以使用GeometricObject,但这看起来很笨拙。

我还想过让Box返回一个calculate_something手动插入到正在使用的结构中,但是返回调用该方法的相同结构类型的人体工程学会被破坏(其中在公共场合/特质中是浪费。)

如何在没有让它成为特质的情况下让它变得井井有条?

1 个答案:

答案 0 :(得分:4)

您似乎想要关联类型

pub trait Algorithm<T> {
    type Output;

    fn calculate_something(&self) -> Result<Self::Output, Error>;
}

impl<T> Algorithm<T> for Sphere<T> {
    type Output = Sphere<T>;

    fn calculate_something(&self) -> Result<Self::Output, Error> {
        unimplemented!()
    }
}

impl<T> Algorithm<T> for Hyperbola<T> {
    type Output = Hyperbola<T>;

    fn calculate_something(&self) -> Result<Self::Output, Error> {
        unimplemented!()
    }
}

are described in detail中的关联类型The Rust Programming Language。我强烈建议阅读整本书,以熟悉Rust提供的功能类型。

另一种解决方案是在特征上定义另一种泛型:

pub trait Algorithm<T, Out = Self> {
    fn calculate_something(&self) -> Result<Out, Error>;
}

impl<T> Algorithm<T> for Sphere<T> {
    fn calculate_something(&self) -> Result<Sphere<T>, Error> {
        unimplemented!()
    }
}

impl<T> Algorithm<T> for Hyperbola<T> {
    fn calculate_something(&self) -> Result<Hyperbola<T>, Error> {
        unimplemented!()
    }
}

然后您需要决定When is it appropriate to use an associated type versus a generic type?