4个版本
0.3.1 | 2022年1月10日 |
---|---|
0.3.0 | 2022年1月10日 |
0.2.2 | 2021年11月11日 |
0.2.1 | 2021年11月10日 |
在算法类别中排名第2137
120KB
1.5K SLoC
generic-str
Rust中真正的唯一字符串类型!
本项目旨在验证我几个月前的一个想法。有很多不安全代码,并且需要使用nightly版本。在以下环境中测试:
cargo 1.58.0-nightly (2e2a16e98 2021-11-08)
说明
Rust有几种不同的字符串类型,其中两种主要的竞争者是
&str
,它是一个'字符串引用'。它是不可变的,并且其可变性受到限制。String
是一个'所有者字符串'。它是可变的,并且可以简单地进行修改。
事实证明,这两种字符串并没有太大的区别。str
只是一个由[u8]
字节切片支持的字符串。同样,String
也只是一个由某种形式的Vec<u8>
支持的字符串。
那么它们为什么会是不同的类型呢?我们理论上不能有像这样的东西吗?
type str = StringBase<[u8]>;
type String = StringBase<Vec<u8>>;
这就是本项目的内容。它与标准库字符串的功能对等性很高。也实现了许多标准特质的实现。
generic-vec
关于是否将Allocator
作为自定义Vec
存储的最佳抽象进行了一些讨论。[有关讨论](https://internals.rust-lang.org/t/is-custom-allocators-the-right-abstraction/13460)。我对这个概念非常感兴趣,并在本项目使用了RustyYato提供的[实现](https://github.com/RustyYato/generic-vec)。
所以现在我有
use generic_vec::{GenericVec, raw::Heap};
pub type String<A = Global> = OwnedString<u8, Box<[MaybeUninit<u8>], A>>;
pub type OwnedString<S> = StringBase<GenericVec<u8, S>>;
这可能看起来更复杂,但你说得对。在实现上,GenericVec<U, Heap<U, A>>
应该与Vec<u8>
相同,因此在功能上应该与之前相同。
但是,凭借这个存储后端系统的额外功能,它允许静态分配但可调整大小的†字符串!
pub type ArrayString<const N: usize> = OwnedString<[MaybeUninit<u8>; N]>;
并且我可以重用之前实现String
时使用的所有相同代码,因为所有这些都在基础OwnedString
类型上实现,用于需要可调整大小的字符串操作。
†:显然,它们不能调整大小超过预定义的
N
值,并且如果你尝试超过这个值,它将引发恐慌。
依赖关系
~145KB