我有一个名为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
手动插入到正在使用的结构中,但是返回调用该方法的相同结构类型的人体工程学会被破坏(其中在公共场合/特质中是浪费。)
如何在没有让它成为特质的情况下让它变得井井有条?
答案 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?