Приведение типов с общим целым числом

Я работаю над функцией, которую я хотел бы сделать универсальной для всех целочисленных типов. Поэтому я использовал черту Integer из ящика numhttps://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

Как я могу привести типовое целое число? Спасибо,

Как создавать пользовательские общие типы в Python (50/100 дней Python)
Как создавать пользовательские общие типы в Python (50/100 дней Python)
Помимо встроенных типов, модуль типизации в Python предоставляет возможность определения общих типов, что позволяет вам определять типы, которые могут...
0
0
65
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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.

Pioneer_11 05.04.2023 07:35

Другие вопросы по теме