Есть crate
num.
У него есть trait Num, который описывает свойства всех числовых типов в Rust (как примитивных, так и не очень).
В не шаблонном коде я могу себе позволить скастовать любой числовой тип к любому другому (ответственность за сужение типов я беру на себя). Однако я не могу найти тот же способ для шаблонного кода.
К примеру, есть у меня тип T, который реализует Num. Скорее всего, очевидно, что его можно кастовать к любому другому типу, реализующий Num (во всяком случае, примитивные типы - точно можно).
Но компайлер раста говорит мне, что это нетривиальный каст (в нем задействованы нетривиальные типы - T, даже если это обычный u32, T всё равно нетривиальный, потому как все проверки проводятся до инстанцирования, что бесит, где мои плюсы?) и что нужно юзать либо Into, либо From (к сожалению, это рантайм).
Изначально код был такой, я и ожидал, что он не скомпилится:
pub fn foo<U>(bar: U) -> u8
where
U: Num,
{
bar as u8
}
Выхлоп:
error[E0605]: non-primitive cast: `U` as `u8`
--> src\map\chunk.rs:54:9
|
54 | bar as u8
| ^^^^^^^^^
|
= note: an `as` expression can only be used to convert between primitive types. Consider using the `From` trait
Потом я сделал как просили в ошибке:
pub fn foo<U>(bar: U) -> u8
where
U: Num + Into<u8>,
{
bar.into()
}
fn main() {
let float = 0f32;
foo(float);
}
Ошибка:
error[E0277]: the trait bound `u8: std::convert::From<f32>` is not satisfied
--> src\main.rs:45:5
|
36 | pub fn foo<U>(bar: U) -> u8
| ---
37 | where
38 | U: Num + Into<u8>,
| -------- required by this bound in `foo`
...
45 | foo(float);
| ^^^ the trait `std::convert::From<f32>` is not implemented for `u8`
|
= help: the following implementations were found:
<u8 as std::convert::From<bool>>
<u8 as std::convert::From<std::num::NonZeroU8>>
= note: required because of the requirements on the impl of `std::convert::Into<u8>` for `f32`
Если кто-то с этим сталкивался, то подскажите, плиз, как вы это решили.