as
выполняет только примитивные приведения между встроенными числовыми типами, но Unsigned
может быть реализовано для ваших собственных типов и т. Д. c. Вот почему as
не работает.
Вы можете использовать черту TryFrom
:
use num::traits::Unsigned;
use std::collections::HashMap;
use std::convert::TryFrom;
fn test<T>(strings: Vec<String>) -> HashMap<String, T>
where
T: Unsigned + TryFrom<usize>,
<T as std::convert::TryFrom<usize>>::Error: Debug, // only for unwrap()
{
let mut string_map: HashMap<String, T> = HashMap::new();
for (i, string) in strings.iter().enumerate() {
string_map.insert(string.clone(), T::try_from(i).unwrap());
}
string_map
}
fn main() {
let result: HashMap<_, u16> = test(vec!["abc".into(), "def".into()]);
}
Теоретически вы можете использовать From
вместо TryFrom
, но в На практике большинство целочисленных типов, например u8
, u16
, u32
, не гарантированно соответствуют usize
. Так что TryFrom
и обработка ошибок необходима.