Я работаю над функцией, которую я хотел бы сделать универсальной для всех целочисленных типов. Поэтому я использовал черту Integer
из ящика num
https://docs.rs/num/latest/num/trait.Integer.html однако моя функция требует, чтобы my мог выполнять приведение типов как в, так и из моего тип ввода напр.
fn main() {
test(54_u8);
}
fn test<T> (x: T)
where T: num::Integer + std::fmt::Display {
assert_eq!(10_u64, x as u64);
assert_eq!(54_i32 as T, x);
}
Где код не работает с сообщением об ошибке
an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
Как я могу привести типовое целое число? Спасибо,
num::FromPrimitive и num::ToPrimitive могут помочь переключаться между num::Integer
и конкретным типом.
fn main() {
test(10_u8);
test(54_u8);
}
fn test<T>(x: T)
where
T: num::Integer + num::FromPrimitive + num::ToPrimitive + Copy,
{
if T::from_u64(10) == Some(x) {
println!("this is ten");
}
if let Some(54) = x.to_i32() {
println!("this is fifty-four");
}
}
В этом же ящике находятся трейты num::FromPrimitive и num::ToPrimitive. Вы можете использовать их как
fn test<T> (x: T)
where T: num::FromPrimitive + num::ToPrimitive + std::fmt::Debug + Eq + Copy {
assert_eq!(10_u64, x.to_u64());
assert_eq!(T::from_i32(54), x);
}
Или вы можете использовать стандартную библиотеку Into/From (или TryInto/TryFrom, если вы хотите, чтобы преобразование не удалось):
fn test<T> (x: T)
where T: From<i32> + Into<u64> + std::fmt::Debug + Eq + Copy {
assert_eq!(10_u64, x.into());
assert_eq!(T::from(54_i32), x);
}
Спасибо. В качестве примечания для всех, кто просматривает этот пример, первый блок кода, показанный выше, не будет работать, поскольку вызовы
to
иfrom
возвращают параметр, а не значение, поэтому вам нужно иметь дело с возвращаемымoption
. Эта опция может дать вамErr
в случае, если у вас есть что-то вродеT
типаu8
, и вы пытаетесьT::from_i32(1000)
, поэтому стоит иметь дело с вариантомErr
.