我正在尝试创建一个泛型结构,它使用"整数类型"来引用数组.出于性能原因,我希望能够轻松指定是否使用u16,u32或u64.像这样的东西(显然是无效的Rust代码):
struct Foo<T: u16 or u32 or u64> { ... }
Run Code Online (Sandbox Code Playgroud)
有没有办法表达这个?
对于数组的引用,通常只使用一个usize而不是不同的整数类型.
但是,要做到你是什么,你可以创建后的新特点,实现该特性的u16,u32并且u64,然后限制吨至您的新特点.
pub trait MyNewTrait {}
impl MyNewTrait for u16 {}
impl MyNewTrait for u32 {}
impl MyNewTrait for u64 {}
struct Foo<T: MyNewTrait> { ... }
Run Code Online (Sandbox Code Playgroud)
然后,您还可以添加方法上MyNewTrait和impls到封装特定的逻辑u16,u32和u64.
有时您可能想要使用具有enumtrait bound的而不是泛型类型。例如:
enum Unsigned {
U16(u16),
U32(u32),
U64(u64),
}
struct Foo { x: Unsigned, ... };
Run Code Online (Sandbox Code Playgroud)
与为现有类型实现新特征相比,创建新类型的一个优点是您可以向新类型添加外部特征和固有行为。你可以实现你喜欢的任何特性Unsigned,比如Add,Mul等等。当Foo包含一个时Unsigned,实现特性Unsigned不会影响Foo像将它们添加为Foo参数的边界(例如Foo<T: Add<Output=Self> + PartialCmp + ...>)的签名。另一方面,您仍然必须实现每个特征。
另一件要注意的事情:虽然您通常总是可以创建一个新类型并为其实现一个特征,但枚举是“关闭的”:您不能在Unsigned不触及其实现的其余部分的情况下添加新类型,就像您使用过的那样一个特质。这可能是好事也可能是坏事,这取决于您的设计要求。
“性能原因”有点模棱两可,但是如果您正在考虑存储很多Unsigned都是相同内部类型的s,那么:
struct Foo([Unsigned; 1_000_000]);
Run Code Online (Sandbox Code Playgroud)
存储一百万u16秒会浪费大量空间,您仍然可以制作Foo泛型!只需实现From<u16>, From<u32>, 和From<u64>forUnsigned并改为写这个:
struct Foo<T: Into<Unsigned>>([T; 1_000_000]);
Run Code Online (Sandbox Code Playgroud)
现在您只有一个简单的 trait 绑定在 上T,您不会浪费标签和填充空间,并且处理的函数T总是可以将其转换Unsigned为进行计算。甚至可以完全优化转换成本。
| 归档时间: |
|
| 查看次数: |
1036 次 |
| 最近记录: |