5 个版本 (破坏性更新)
0.5.0 | 2022年12月17日 |
---|---|
0.4.0 | 2022年12月17日 |
0.3.0 | 2022年5月22日 |
0.2.0 | 2022年1月1日 |
0.1.0 | 2022年1月1日 |
#22 in #number
18KB
309 行代码(不含注释)
extent
这是 std::ops::{Range,RangeInclusive} 的一个替代品,避免了这些类型的一些特性(非 Copy,无法在不使用额外的 bool 的情况下产生空范围,直接实现 Iterator 等)。请参阅 https://ridiculousfish.com/blog/posts/least-favorite-rust-type.html 和 https://kaylynn.gay/blog/post/rust_ranges_and_suffering 以了解其罪行清单。
今天我恰好在我自己的一个 crate 中编写这个类型时看到了第二篇文章,所以我决定将其拆分出来,并作为一个 crate 发布供其他人使用。它有一些特性和限制,但比我使用的内置类型更符合我的需求。以下是我的选择:
-
Extent
表示一个包含数字的范围,其中数字是来自(相当标准的)num-traits crate 的N:PrimInt
。它是包含的,因为(至少是最明显的)排除范围无法表示数字类型的最大值,在我的经验中,这通常是需要表示的! -
Extent
使用 exactly 2 个数字和没有额外的标志或浪费的空间。 -
Extent
可以表示空范围。空范围以{lo=1, hi=0}
的规范化形式表示。这是唯一的这种情况,其中lo > hi
,并且只能通过静态函数empty
或 IO 方向的函数new_unchecked
来构造。端点的典型访问器lo()
和hi()
返回一个Option<N>
,在空的情况下返回None
。如果您想得到原始形式(例如,用于 IO),可以调用lo_unchecked()
或hi_unchecked()
,这些函数被标记为 unsafe,因为它们不反映重要的lo <= hi
不变式。 -
所有非空情况都在
new
中强制执行lo <= hi
。如果你向new
传递hi > lo
,则值将被交换(即你可以从点的任意顺序构造;它们将被存储在顺序中)。如果你从原始 IO 值构建,可以使用new_unchecked
,它不会交换,只会将无序范围规范化为empty()
,但也是不安全的。 -
Extent
实现了Copy
(以及所有其他标准功能)。 -
Extent
没有实现Iterator
,但它有一个iter
方法,该方法将Extent
复制到ExtentIter
,它实现了Iterator
。 -
还有一个
ExtentRevIter
用于递减计数。 -
提供了一些基本的集合运算符(并集、交集、包含),但并没有太多花哨的功能。
欢迎提交补丁来丰富这一点,尽管我会尽量保持它相对简单,并专注于数字范围的用例,而不是“任意事物范围”。
许可证:MIT OR Apache-2.0
依赖项
~155KB