"polymorphic" return 的 Rust 特性的简单组织
Simple organization of Rust traits for "polymorphic" return
我有一个名为 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
}
现在我有一个用于 Sphere
的 Algorithm
的工作实现:
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
和 return 一个新的 Sphere
。它以这种方式实现是因为 Algorithm
需要使用额外的几何信息来计算 calculated_result
— 从语义上讲,它是几何上的实现更有意义,其结果恰好与一个相关联或更多 Frame
s.
我想为 Hyperbola
实现相同的 Algorithm
。其实已经很接近了,trait一样是有道理的,但是要return一个Sphere<T>
.
就没意义了
我知道我可以添加另一个特征,例如 GeometricObject
并添加另一层构图,但这似乎过分了。我想我也许可以使用 Box
,但这看起来很笨拙。
我还想过 calculate_something
return 手动插入一个 Vec<T>
到任何正在使用的结构中,但是 return 的人体工程学是一样的调用该方法的结构类型被破坏(这在 public impl/trait 中是一种浪费)。
我怎样才能在不让它一直保持特征的情况下组织起来?
您似乎想要一个关联类型:
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 in 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!()
}
}
然后你需要决定
我有一个名为 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
}
现在我有一个用于 Sphere
的 Algorithm
的工作实现:
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
和 return 一个新的 Sphere
。它以这种方式实现是因为 Algorithm
需要使用额外的几何信息来计算 calculated_result
— 从语义上讲,它是几何上的实现更有意义,其结果恰好与一个相关联或更多 Frame
s.
我想为 Hyperbola
实现相同的 Algorithm
。其实已经很接近了,trait一样是有道理的,但是要return一个Sphere<T>
.
我知道我可以添加另一个特征,例如 GeometricObject
并添加另一层构图,但这似乎过分了。我想我也许可以使用 Box
,但这看起来很笨拙。
我还想过 calculate_something
return 手动插入一个 Vec<T>
到任何正在使用的结构中,但是 return 的人体工程学是一样的调用该方法的结构类型被破坏(这在 public impl/trait 中是一种浪费)。
我怎样才能在不让它一直保持特征的情况下组织起来?
您似乎想要一个关联类型:
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 in 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!()
}
}
然后你需要决定