#list #linked-list #generic #functional #no-alloc #no-std

no-std tlist

类型级别的链表(类型链表)和操作它们的类型级别的 '函数'。由于 TList 使用 GAT 实现,使用非常便捷。

6 个版本

0.7.0 2023 年 4 月 10 日
0.6.2 2023 年 4 月 4 日
0.5.1 2023 年 4 月 4 日

2070Rust 模式

Download history 3/week @ 2024-04-19 2/week @ 2024-05-24 2/week @ 2024-05-31 1/week @ 2024-06-28 16/week @ 2024-07-05

84 每月下载量
overloaded_literals 中使用

MIT 许可证

22KB
180

TList — 最新版本 许可证

Rust 的类型级别链表。

文档

如果需要在类型内部跟踪一个 列表 的类型,并以泛型方式操作它们,例如查看列表中的第一个类型,连接列表,反转列表等,这些将非常有用。

构建 TList 最简单的方法是使用 TList! 宏。

use tlist::*;

type MyList = TList![String, usize, bool];

类型级别函数

通过在 crate 中定义的许多类型别名之一来操作 TList。这些是很好读的别名,内部使用 TListNonEmpty 特性定义中的许多泛型关联类型(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]的两个构造函数TNilTCons都是零大小类型(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

启用时,包含typenum crate作为依赖项,并使用它来提供Len)和IsEmpty)关联类型,它们是LEN和IS_EMPTY关联常量的类型级别等价物。

默认禁用。

依赖项

~39KB