6个版本
0.2.0-alpha2 | 2022年6月11日 |
---|---|
0.1.0-alpha6 | 2020年8月6日 |
0.1.0-alpha4 | 2020年7月14日 |
0.1.0-alpha3 | 2020年7月12日 |
#168 在 #slice
17KB
215 行
Loaf
为什么要有切片,当你可以有面包时呢?
这是什么
有时候你知道切片必须至少有一个元素,但是Rust通过从例如split_first()
方法中的Option
执行“最后一刻决定”来强制你这样做。
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源代码
安全性
只要两个数组可以解释为一个更大的数组,反之亦然,一切应该都是正确的