6 个版本
0.7.0 | 2023 年 4 月 10 日 |
---|---|
0.6.2 | 2023 年 4 月 4 日 |
0.5.1 | 2023 年 4 月 4 日 |
2070 在 Rust 模式 中
84 每月下载量
在 overloaded_literals 中使用
22KB
180 行
TList —
Rust 的类型级别链表。
如果需要在类型内部跟踪一个 列表 的类型,并以泛型方式操作它们,例如查看列表中的第一个类型,连接列表,反转列表等,这些将非常有用。
构建 TList 最简单的方法是使用 TList! 宏。
use tlist::*;
type MyList = TList![String, usize, bool];
类型级别函数
通过在 crate 中定义的许多类型别名之一来操作 TList。这些是很好读的别名,内部使用 TList 和 NonEmpty 特性定义中的许多泛型关联类型(GAT)。
你可以将这些类型别名视为类型级别的函数版本。与普通函数不同,它们在编译时运行,在类型级别上
use tlist::TList;
use static_assertions::assert_type_eq_all as assert_type_eq;
type Things = TList![String, usize, bool];
type Sgniht = tlist::Reverse<Things>;
assert_type_eq!(Sgniht, TList![bool, usize, String]);
type MoreThings = tlist::Concat<Things, TList![u8, u8, u8]>;
assert_type_eq!(MoreThings, TList![String, usize, bool, u8, u8, u8]);
这意味着你可以在你定义的任何类型、特性和(普通)函数的 where
子句中使用它们。TList 实现 Default,这使得将其作为结构体或枚举的字段添加变得非常容易。(它是一个 ZST,因此它在运行时没有大小)。
use tlist::TList;
#[derive(Debug)]
pub struct MyStruct<List: TList> {
normal_data: String,
special_data: List,
}
let foo = MyStruct::<TList![usize, bool]> {
normal_data: "Hello".to_string(),
special_data: Default::default()
};
println!("{:?}", foo);
便捷性
大多数处理类型级别操作的crate都为每个操作引入一个新的trait。这种方法的重大缺点是,这些操作迫使在每个调用操作的地方都添加一个额外的trait约束。
这种技术使得trait约束难以阅读。此外,它组合得非常糟糕,因为任何使用你在其中添加了约束的struct、trait或函数的地方现在也需要那个约束。以及这些调用者...等等!‘约束地狱’。
在Rust的旧版本中,这是实现类型级别操作的唯一方法。但是自从v1.65中GATs(泛型关联类型)的稳定化以来,情况就不再是这样了。
TList将所有类型级别操作实现为同一trait上的多个GAT。因此,你只需要这一个约束,这使得使用它更加方便。
编译时安全性
在NonEmpty
TLists上尝试执行仅在Empty
TLists上定义的操作会导致编译时错误
use tlist::TList;
use static_assertions::assert_type_eq_all as assert_type_eq;
type Boom = tlist::First<TList![]>;
assert_type_eq!(Boom, u8); // <- Compile error: Trait NonEmpty is not implemented for TNil
请注意,编译错误仅发生在查看输出的第二行,因为Rust会惰性地进行类型展开,所以如果你从未使用过‘不可能’的结果,编译器不会报错。
对于其他‘部分’操作也是类似的情况。
效率
[TList]的两个构造函数TNil
和TCons
都是零大小类型(ZST)。这意味着任何TList也将是零大小,并在程序运行之前完全消失。
因为所有的计算都在编译时进行,所以你的程序运行时不会受到影响。
兼容性
no_std
TList只依赖于core
,因此与no_std
完全兼容。无需禁用任何功能即可启用no_std
支持。
MSRV
TList支持的最小Rust版本是1.65:该实现广泛使用了GATs。
依赖项
tlist crate默认没有依赖项。当启用typenum
crate时,会包含同名crate,该crate用于许多额外的trait(见下文)。
无安全代码
此crate不包含任何不安全代码。
功能标志
typenum
启用时,包含
crate作为依赖项,并使用它来提供Len)和IsEmpty)关联类型,它们是LEN和IS_EMPTY关联常量的类型级别等价物。typenum
默认禁用。
依赖项
~39KB