2016-08-22 45 views
0
pub type ESign = i8; 
const CONCAVE: i8 = -1; 
const TANGENTIAL: i8 = 0; 
const CONVEX: i8 = 1; 

fn signum_enum(a: f64) -> ESign { 
    if a > 0.0 { CONVEX } else if a < 0.0 { CONCAVE } else { TANGENTIAL } 
} 

pub fn area_tri_signed_v2_alt_2x(v1: &[f64; 2], v2: &[f64; 2], v3: &[f64; 2]) -> f64 { 
    ((v1[0] * (v2[1] - v3[1])) + (v2[0] * (v3[1] - v1[1])) + (v3[0] * (v1[1] - v2[1]))) 
} 

pub fn span_tri_v2_sign(v1: &[f64; 2], v2: &[f64; 2], v3: &[f64; 2]) -> ESign { 
    return signum_enum(area_tri_signed_v2_alt_2x(v3, v2, v1)); 
} 

我設法使這些成爲泛型函數,但我最終不得不重複類型邊界。如何重用泛型函數類型邊界?

use std::ops::{Mul, Sub, Add}; 

fn signum_enum<T: Default + PartialOrd>(a: T) -> ESign { 
    let zero = T::default(); 
    if a > zero { CONVEX } else if a < zero { CONCAVE } else { TANGENTIAL } 
} 

pub fn area_tri_signed_v2_alt_2x<T: Default + PartialOrd + Copy + Mul<Output=T> + Sub<Output=T> + Add<Output=T>>(
    v1: &[T; 2], 
    v2: &[T; 2], 
    v3: &[T; 2]) -> T 
{ 
    ((v1[0] * (v2[1] - v3[1])) + (v2[0] * (v3[1] - v1[1])) + (v3[0] * (v1[1] - v2[1]))) 
} 

pub fn span_tri_v2_sign<T: Default + PartialOrd + Copy + Mul<Output=T> + Sub<Output=T> + Add<Output=T>>(
    v1: &[T; 2], 
    v2: &[T; 2], 
    v3: &[T; 2]) -> ESign 
{ 
    return signum_enum(area_tri_signed_v2_alt_2x(v3, v2, v1)); 
} 

有沒有辦法在一個地方定義這些功能,並在多個泛型函數中重用它們?

回答

2

最簡單的方法是定義一個新的特點,其都需要所有你正在處理的界限:

pub trait Floatlike: Default + PartialOrd + Copy + 
    Mul<Output=Self> + Sub<Output=Self> + Add<Output=Self> {} 

,並通過滿足這些邊界所有類型的實現:

impl<T> Floatlike for T where T: Default + PartialOrd + Copy + 
    Mul<Output=T> + Sub<Output=T> + Add<Output=T> {} 

和然後綁定在該特徵上:

pub fn area_tri_signed_v2_alt_2x<T: Floatlike>(...) 
pub fn span_tri_v2_sign<T: Floatlike>(...)