Generics 如何生成一般绝对值函数?

Generics 如何生成一般绝对值函数?,generics,rust,traits,Generics,Rust,Traits,我正在尝试编写一个通用函数,用于计算任何有符号整数类型的绝对值。当值为最低可能负值时,它应返回一个错误,例如8位abs(-128)无法表示 我让它为i8工作: pub fn abs(x: i8) -> Result<i8, String> { match x { x if x == -128i8 => Err("Overflow".to_string()), // I know could just use x.abs() now

我正在尝试编写一个通用函数,用于计算任何有符号整数类型的绝对值。当值为最低可能负值时,它应返回一个错误,例如8位
abs(-128)
无法表示

我让它为i8工作:

pub fn abs(x: i8) -> Result<i8, String> {
    match x {
        x if x == -128i8 => Err("Overflow".to_string()),
        // I know could just use x.abs() now but this illustrates a problem in the generic version below...
        x if x < 0i8 => Ok(-x),
        _ => Ok(x),
    }
}

fn main() {
    println!("{:?}", abs(-127i8));
    println!("{:?}", abs(-128i8));
}
错误[E0008]:无法通过移动到模式保护进行绑定
-->src/main.rs:9:9
|
9 | x如果xOk(-x),
|^将值移动到模式保护中
如何确定一般最小值?基本上是C++的代码等价> STD::数值限制::()/代码>? 您需要从
num traits
num
板条箱中获得一个
min\u值
方法:

pub fn abs<T>(x: T) -> Result<T, String>
where
    T: Signed + Integer + Zero + Neg + Bounded + Copy,
{
    match x {
        x if x == T::min_value() => Err("Overflow".to_string()),
        x if x < T::zero() => Ok(-x),
        _ => Ok(x),
    }
}

这将把函数的“肉”委托给现有的代码,而这些代码正是您想要的,这样您就没有太多出错的空间

解决了我的两个问题谢谢。我同意重新发明轮子通常是个坏主意,但我发现它对学习有用。毕竟,我可以通过执行`-128i8.abs()来获取错误,我建议返回一个
选项
,因为这里没有真正的错误,而是一个有效的计算。这类似于“hellow是的,我同意”。但我已经用OP要求的签名回答了。
pub fn abs<T>(x: T) -> Result<T, String>
where
    T: Signed + Integer + Zero + Neg + Bounded + Copy,
{
    match x {
        x if x == T::min_value() => Err("Overflow".to_string()),
        x if x < T::zero() => Ok(-x),
        _ => Ok(x),
    }
}
pub fn abs<T>(x: T) -> Result<T, String>
where
    T: Signed + Integer + Zero + Neg + CheckedSub,
{
    if x < T::zero() {
        T::zero()
            .checked_sub(&x)
            .ok_or_else(|| String::from("Overflow"))
    } else {
        Ok(x)
    }
}