2016-08-22 2 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)); 
} 

Ich habe es geschafft, diese in generische Funktionen zu machen, aber ich musste schließlich Typgrenzen zu duplizieren.Wie generische Funktionstypgrenzen wiederverwenden?

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)); 
} 

Gibt es eine Möglichkeit, diese Funktionen an einer Stelle zu definieren und sie in mehreren generischen Funktionen wiederzuverwenden?

Antwort

2

Der einfachste Weg ist es, ein neues Merkmal zu definieren, die sowohl alle Grenzen erfordert, dass Sie es zu tun mit:

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

und wird von allen Arten implementiert, die diese Grenzen erfüllen:

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

und dann gebunden an diesem Merkmal:

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