Generics 如何重用通用函数类型边界? pub类型ESign=i8; 常数凹:i8=-1; 常切:i8=0; 常数凸:i8=1; fn符号枚举(a:f64)->设计{ 如果a>0.0{凸}否则如果af64{ ((v1[0]*(v2[1]-v3[1]))+(v2[0]*(v3[1]-v1[1]))+(v3[0]*(v1[1]-v2[1])) } 发布fn span_tri_v2_sign(v1:&[f64;2],v2:&[f64;2],v3:&[f64;2])->设计{ 返回符号枚举(区域符号v2替换2x(v3,v2,v1)); }

Generics 如何重用通用函数类型边界? pub类型ESign=i8; 常数凹:i8=-1; 常切:i8=0; 常数凸:i8=1; fn符号枚举(a:f64)->设计{ 如果a>0.0{凸}否则如果af64{ ((v1[0]*(v2[1]-v3[1]))+(v2[0]*(v3[1]-v1[1]))+(v3[0]*(v1[1]-v2[1])) } 发布fn span_tri_v2_sign(v1:&[f64;2],v2:&[f64;2],v3:&[f64;2])->设计{ 返回符号枚举(区域符号v2替换2x(v3,v2,v1)); },generics,types,rust,Generics,Types,Rust,我设法将它们转换成泛型函数,但最终不得不复制类型边界 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 ar

我设法将它们转换成泛型函数,但最终不得不复制类型边界

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));
}
使用std::ops:{Mul,Sub,Add};
fn符号枚举(a:T)->设计{
设zero=T::default();
如果a>0{凸}否则如果a<0{凹}否则{切}
}
酒馆fn区域三层签名v2高度2x(
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]))
}
酒吧fn span_tri_v2_标志(
v1:&[T;2],
v2:&[T;2],
v3:&[T;2])->设计
{
返回符号枚举(区域符号v2替换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));
}
pub-like:Default+PartialOrd+Copy+
Mul+Sub+Add{}
并由满足这些界限的所有类型实现:

pub trait Floatlike: Default + PartialOrd + Copy +
    Mul<Output=Self> + Sub<Output=Self> + Add<Output=Self> {}
impl Floatlike for T,其中T:Default+PartialOrd+Copy+
Mul+Sub+Add{}
然后就被这个特质束缚住了:

impl<T> Floatlike for T where T: Default + PartialOrd + Copy + 
    Mul<Output=T> + Sub<Output=T> + Add<Output=T> {}
pub fn区域\u tri\u签名\u v2\u alt\u 2x(…)
发布fn span_tri_v2_标志(…)

最简单的方法是定义一个新的特征,它需要你处理的所有边界:

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));
}
pub-like:Default+PartialOrd+Copy+
Mul+Sub+Add{}
并由满足这些界限的所有类型实现:

pub trait Floatlike: Default + PartialOrd + Copy +
    Mul<Output=Self> + Sub<Output=Self> + Add<Output=Self> {}
impl Floatlike for T,其中T:Default+PartialOrd+Copy+
Mul+Sub+Add{}
然后就被这个特质束缚住了:

impl<T> Floatlike for T where T: Default + PartialOrd + Copy + 
    Mul<Output=T> + Sub<Output=T> + Add<Output=T> {}
pub fn区域\u tri\u签名\u v2\u alt\u 2x(…)
发布fn span_tri_v2_标志(…)