#slice #index #collection #vec #no-std

no-std typed-index-collections

类型索引版本的Rust切片和Vec容器

16个版本 (10个稳定版)

3.1.0 2022年9月2日
3.0.3 2021年5月27日
3.0.2 2020年11月22日
3.0.1 2020年10月30日
0.0.3 2020年7月14日

#204 in 数据结构

Download history 2083/week @ 2024-03-14 2812/week @ 2024-03-21 2308/week @ 2024-03-28 2481/week @ 2024-04-04 2252/week @ 2024-04-11 1826/week @ 2024-04-18 2260/week @ 2024-04-25 1823/week @ 2024-05-02 1985/week @ 2024-05-09 2012/week @ 2024-05-16 1836/week @ 2024-05-23 2316/week @ 2024-05-30 1455/week @ 2024-06-06 2357/week @ 2024-06-13 3074/week @ 2024-06-20 2296/week @ 2024-06-27

9,695 每月下载量
用于 36 个crate (6 个直接使用)

MIT/Apache

155KB
2.5K SLoC

typed-index-collections

CI Latest Version Documentation GitHub license Rust Version

typed-index-collections crate提供了TiSliceTiVec结构体,它们是Rust的slicestd::vec::Vec类型的类型索引版本。

简介

在优化、面向数据设计和使用数组结构体时,大量使用切片和向量而不是引用和智能指针可能是有用的。但是,在处理大量切片和向量时,很容易错误地使用错误的索引,这是常见的错误来源。

关于

此crate提供了TiSlice<K, V>TiVec<K, V>容器,这些容器只能通过指定的索引类型K进行索引。这些容器是围绕切片原语[V]和容器std::vec::Vec<V>的包装。crate容器映射匹配Rust容器的稳定API,尽可能转发。

TiSliceTiVec 可以通过使用 FromIntoAsRefAsMut 特性,轻松转换为匹配的 Rust 容器以及反向转换。此外,它们还公开了原始数据类型的 raw 属性。容器只需要实现 From<usize>Into<usize> 特性,这可以通过 derive_more crate 和 #[derive(From, Into)] 轻松完成。

用法

首先,将以下内容添加到您的 Cargo.toml

[dependencies]
typed-index-collections = "3.1.0"

此 crate 默认依赖于标准库,这对调试和一些额外功能很有用。要在 #![no_std] 上下文中使用此 crate,请在您的 Cargo.toml 中使用 default-features = false,如下所示

[dependencies.typed-index-collections]
version = "3.1.0"
default-features = false
features = ["alloc"]

如果您想使用 derive_moreFrom<usize>Into<usize> 实现添加它到您的 Cargo.toml,如下所示

[dependencies]
derive_more = "0.99"
typed-index-collections = "3.1.0"

示例

使用 derive_more 的简单示例

use typed_index_collections::TiVec;
use derive_more::{From, Into};

#[derive(From, Into)]
struct FooId(usize);

let mut ti_vec: TiVec<FooId, usize> = std::vec![10, 11, 13].into();
ti_vec.insert(FooId(2), 12);
assert_eq!(ti_vec[FooId(2)], 12);

如果使用了错误的索引类型,编译将失败

use typed_index_collections::TiVec;
use derive_more::{From, Into};

#[derive(From, Into)]
struct FooId(usize);

#[derive(From, Into)]
struct BarId(usize);

let mut ti_vec: TiVec<FooId, usize> = std::vec![10, 11, 13].into();

ti_vec.insert(BarId(2), 12);
//            ^^^^^^^^ expected struct `FooId`, found struct `BarId`
assert_eq!(ti_vec[BarId(2)], 12);
//         ^^^^^^^^^^^^^^^^ the trait ... is not implemented for `BarId`

另一个带有 derive_more 的更详细的示例

use typed_index_collections::{TiSlice, TiVec};
use derive_more::{From, Into};

#[derive(Clone, Copy, Debug, From, Into, Eq, PartialEq)]
struct FooId(usize);

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
struct Foo {
    value: usize,
}

let first = Foo { value: 1 };
let second = Foo { value: 2 };

let slice_ref = &[first, second][..];
let vec = std::vec![first, second];
let boxed_slice = std::vec![first, second].into_boxed_slice();

let ti_slice_ref: &TiSlice<FooId, Foo> = slice_ref.as_ref();
let ti_vec: TiVec<FooId, Foo> = vec.into();
let ti_boxed_slice: std::boxed::Box<TiSlice<FooId, Foo>> = boxed_slice.into();

assert_eq!(ti_vec[FooId(1)], second);
assert_eq!(ti_vec.raw[1], second);
assert_eq!(ti_vec.last(), Some(&second));
assert_eq!(ti_vec.last_key_value(), Some((FooId(1), &second)));
assert_eq!(ti_vec.iter_enumerated().next(), Some((FooId(0), &first)));

let _slice_ref: &[Foo] = ti_slice_ref.as_ref();
let _vec: std::vec::Vec<Foo> = ti_vec.into();
let _boxed_slice: std::boxed::Box<[Foo]> = ti_boxed_slice.into();

文档

API 文档

功能标志

类似包

  • typed_index_collection提供了一个API非常有限的Vec包装器。索引是u32的包装器,不可定制,只能索引特定类型的容器。
  • indexed_vec是来自librustc_indexIndexVec结构的最近副本,但其API与标准Rust std::vec::Vec不同,并且没有类型化的切片slice替代方案。
  • index_vec提供了slicestd::vec::Vec包装器,API更接近标准API。但它隐式允许您在get方法和索引表达式中使用usize,这会降低类型安全性,并且使用宏define_index_type!生成一个新的类型化索引结构,隐式实现了许多我认为只有在需要时才应该使用特定于此的crates实现的trait,例如derive_more

许可证

在以下任一许可证下授权

由您选择。

贡献

除非您明确声明,否则根据Apache-2.0许可证定义,您有意提交以包含在作品中的任何贡献,均应作为上述双许可处理,不附加任何额外条款或条件。

依赖项

~170KB