2016-12-27 71 views
3

我有一個基本的結構叫做Frame,這對一堆計算很有用:。簡單的「多態」返回的Rust特性的組織

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工作實施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 - 從語義上講,它更適合作爲幾何體的實現,其結果恰好與一個或多個Frame相關聯。

我想爲Hyperbola實施相同的Algorithm。實際上,它非常接近於同一個特徵,並且這個特徵是相同的,但它返回Sphere<T>沒有任何意義。

我知道我可以添加另一個特徵,如GeometricObject並添加另一層構圖,但看起來過多。我想我可以使用Box,但這看起來很笨拙。

我還想到具有calculate_something回報Vec<T>手動插入取結構是在使用中,但隨後的返回相同的結構類型的方法被稱爲上也毀(這是在一個公共IMPL浪費的人體工程學/特徵)。

我怎樣才能得到這個有組織的,而不是一直下降的特點?

回答

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 detailThe Rust Programming Language。 I 強烈推薦閱讀整本書,熟悉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?

+0

這是令人興奮的!我並沒有真正理解本書的這部分內容,因爲我沒有做好準備,但現在我有了一些好的背景。 –