#slice #array #no-std

no-std loaf

为什么要有切片,当你可以有面包时呢?

6个版本

0.2.0-alpha22022年6月11日
0.1.0-alpha62020年8月6日
0.1.0-alpha42020年7月14日
0.1.0-alpha32020年7月12日

#168#slice

MIT 许可证

17KB
215

Loaf

为什么要有切片,当你可以有面包时呢?

这是什么

有时候你知道切片必须至少有一个元素,但是Rust通过从例如split_first()方法中的Option执行“最后一刻决定”来强制你这样做。

crates.io docs.rs


lib.rs:

为什么要有切片,当你可以有面包时呢?

这是什么

有时候你知道切片必须至少有一个元素,但是Rust通过从例如split_first()方法中的Option执行“最后一刻决定”来强制你这样做。

[Loaf]通过其定义保证了至少有一个元素。

它是如何工作的

首先,让我们考虑一个简单的切片

let x: &[u8] = &[10, 42, 0, 7, 91];

&[u8]在底层实际上只是一个指向缓冲区的指针和其长度(一个胖指针)

[ ptr: *const u8 | len: usize = 5 ]
   |                |
   |                v       
   |    | <-       [u8]       -> |
   |    +----+----+----+----+----+
   +--->| 10 | 42 | 00 | 07 | 91 |
        +----+----+----+----+----+

这是因为[u8]的大小只能在运行时知道。

Rust还允许定义一个结构,其末尾正好有一个动态大小的类型。

struct LoafT<u8, 2> {
    loaf: [u8; 2],
    rest: [u8],
}
let x: &[u8] = &[10, 42, 0, 7, 91];
let loaf: &LoafN<u8, 2> = abracadabra!(slice);

在这种情况下,len也包含了[u8]的长度。

[ ptr: *const ?? | len: usize = 3 ]
   |                     |
   |                     v       
   |    | [u8; 2] | <-  [u8]  -> |
   |    +----+----+----+----+----+
   +--->| 10 | 42 | 00 | 07 | 91 |
        +----+----+----+----+----+

ptr在这里没有明确的类型,因为*const LoafN<u8, 2>本身也是一个胖指针(因为有一个[u8]字段)。

技巧

Rust确实有一种方法可以摆弄胖指针的内部,但是它需要ptr_metadata特性,这仅在nightly版本中可用。这里的技巧是创建一个*mut [T],就像它是*mut Loaf<T>一样,然后将其转换为。

更多详情请参阅Loaf::from_slice源代码

安全性

只要两个数组可以解释为一个更大的数组,反之亦然,一切应该都是正确的

无运行时依赖

功能