Я пытаюсь написать универсальную функцию, которая вычисляет абсолютное значение любого целочисленного типа со знаком.Он должен возвращать ошибку, когда значение является наименьшим возможным отрицательным значением, например, для 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));
}
Я не могу заставить работать универсальную версию.В частности, у меня есть две проблемы:
- Как определить общее минимальное значение?Что такое Rust-эквивалент C ++
std::numeric_limits<T>::min()
?Например, есть std::i32::MIN
, но я не могу написать std::T::MIN
. - Мои общие ошибки реализации на плече сопоставления для отрицательных значений с «невозможно связать при перемещении в шаблонную защиту» (но неуниверсальная версия этого не делает.)
use num::{traits::Zero, Integer, Signed}; // 0.2.0
pub fn abs<T>(x: T) -> Result<T, String>
where
T: Signed + Integer + Zero,
{
match x {
//x if x == ***rust equivalent of std::numeric_limits<T>::min()** => Err("Overflow".to_string()),
x if x < T::zero() => Ok(-x),
_ => Ok(x),
}
}
fn main() {
println!("{:?}", abs(-127i8));
println!("{:?}", abs(-128i8));
}
error[E0008]: cannot bind by-move into a pattern guard
--> src/main.rs:9:9
|
9 | x if x < T::zero() => Ok(-x),
| ^ moves value into pattern guard