#rust #traits #bounds
#Ржавчина #Трейты #границы
Вопрос:
Предположим, у меня есть свой собственный тип в виде структуры кортежа
struct MyType(u8);
И хотел бы реализовать From
признак для других целых типов в общем виде, например
impl From<T> for MyType {
fn from(num: T) -> Self {
MyType((num amp; 0xff) as u8)
}
}
Rust не допускает этого, поскольку у универсальных типов T
нет as
оператора. Как я могу ограничить T
целые типы, чтобы as
их можно было использовать? что-то вроде
impl From<T: Integral> for MyType {...}
Ответ №1:
Вы можете использовать num-traits
ящик.
PrimInt
является соответствующей чертой, которая расширяет NumCast
, что позволяет выполнять преобразование между примитивными числовыми типами.
РЕДАКТИРОВАТЬ: вот пример реализации. Это немного некрасиво, потому что многие из соответствующих преобразований возвращаются Option
, поскольку они не знают заранее, что значения находятся в диапазоне.
impl<T: PrimInt> From<T> for MyType {
fn from(num: T) -> Self {
let clamped = num amp; T::from(0xFFu8).unwrap();
Self(clamped.to_u8().unwrap())
}
}
Комментарии:
1. Вы также можете захотеть конкретно сослаться на приведенный ими пример; где все целые числа реализуются
From<u8>
и, следовательно0xFF
, могут быть преобразованы в них.2. Мне не совсем нравится
T::from
, что возвращает anOption
. В стандартеstd::convert::From
указано, что «Примечание: эта черта не должна завершаться ошибкой. Если преобразование может завершиться неудачей, используйте TryFrom.». Это, похоже, противоречит этой идее. Но спасибо, что указали на num-черты.3. @Miguel Этот
from()
метод не изFrom
признака, скорее это методNumCast
с тем же именем. К сожалению, этоfrom::<u8>
возвращает параметр, но это имеет смысл для таких вещей, как преобразованиеu64
вu32
.4. internals.rust-lang.org/t/… я думаю, это был бы шаг в правильном направлении, с
IntToInt
чертой иwrapping_to()