如何在 Rust 中强制泛型参数为 u8、u16、u32 或 u64 类型?

问题描述 投票:0回答:1

我正在尝试用 Rust 编写一个函数,它应该接受泛型参数 T,但我想强制 T 为无符号整数类型之一(u8、u16、u32 或 u64)。此外,我想限制 T 支持某些按位运算,例如 AND (&) 和 OR (|),以及按位赋值运算符(&= 和 |=)。

这是我迄今为止尝试过的:

fn test<T>(mut x: T)
where
    T: std::fmt::Display
        + BitAnd<u8, Output = T>
        + BitOr<u8, Output = T>
        + BitAndAssign<u8>
        + BitOrAssign<u8>
        + std::cmp::PartialOrd<u8>,
{
    if x >= 2 {
        x &= 4;
    }
    println!("{}", x);
}

但是,此实现仅在 T 为 u8 时有效。当我尝试包含其他类型(如 u16、u32 或 u64)时,它无法编译。

强制 T 成为这些特定无符号整数类型之一并支持所需的按位运算的正确方法是什么?

谢谢您的帮助!

generics rust traits
1个回答
0
投票

如果您想让它适用于所有无符号类型,请在边界中使用

T
而不是
u8

那么你不能直接在代码中使用文字数字,因为不能保证

T
可以从文字数字构造出来,所以添加
T: From<u8>
绑定和显式转换:

fn test<T>(mut x: T)
where
    T: std::fmt::Display
        + BitAnd<T, Output = T>
        + BitOr<T, Output = T>
        + BitAndAssign<T>
        + BitOrAssign<T>
        + std::cmp::PartialOrd<T>
        + From<u8>,
{
    if x >= T::from (2) {
        x &= T::from (4);
    }
    println!("{}", x);
}

游乐场

这也适用于满足约束的任何类型

T
,不限于
u8
u64
(特别是它适用于
usize
)。这在实践中不应该成为问题,但如果您真的想要将自己限制在一组类型中,只需添加一个仅针对您想要的类型实现的标记特征:

trait Marker{}

impl Marker for u8 {}
impl Marker for u16 {}
impl Marker for u32 {}
impl Marker for u64 {}

fn test<T>(mut x: T)
where
    T: std::fmt::Display
        + BitAnd<T, Output = T>
        + BitOr<T, Output = T>
        + BitAndAssign<T>
        + BitOrAssign<T>
        + std::cmp::PartialOrd<T>
        + From<u8>
        + Marker,
{
    if x >= T::from (2) {
        x &= T::from (4);
    }
    println!("{}", x);
}

© www.soinside.com 2019 - 2024. All rights reserved.