&v[2..7] 是怎么做到不复制的?切片里到底存了什么?越界会怎样?空切片和零大小元素的切片指针又是什么?这篇把切片拆成「指针 + 长度」逐项验证。
编译:成功
运行(退出码 0):
&v[..] 指针 = base + 0 字节 长度 10
&v[2..7] 指针 = base + 8 字节 长度 5
&v[5..] 指针 = base + 20 字节 长度 5
&v[2..7][1..3] 指针 = base + 12 字节 长度 2
&v[3..3] (空) 指针 = base + 12 字节 长度 0
数组 [u8; 4] 转 &[u8]:长度 4,数据地址相同 true
size_of::<&[u32]>() = 16(指针 8 + 长度 8)数组、切片与 Vec 的区别见数组、切片与 Vec;trait object 的胖指针见Trait Object 的胖指针。
编译:成功
运行(退出码 0):
改 &mut v[1..4] 的第 0、2 个元素后 v = [1, 20, 3, 40, 5, 6]
split_at_mut(3) 得到两个不重叠的 &mut 切片,分别改后 v = [100, 20, 3, 400, 5, 6]
源码:
1 | fn main() { let mut v = vec![1, 2, 3, 4]; let a = &mut v[0..3]; let b = &mut v[2..4]; a[0] = 1; b[0] = 2; }
编译:失败
error[E0499]: cannot borrow `v` as mutable more than once at a time
--> <实验目录>/src/u116c.rs:1:78
|
1 | fn main() { let mut v = vec![1, 2, 3, 4]; let a = &mut v[0..3]; let b = &mut v[2..4]; a[0] = 1; b[0] = 2; }
| - ^ ---- first borrow later used here
| | |
| | second mutable borrow occurs here
| first mutable borrow occurs here
|
= help: use `.split_at_mut(position)` to obtain two mutable non-overlapping sub-slices
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0499`. 编译:成功
【范围越界】退出码 101:['range end index 5 out of range for slice of length 3']
编译:成功
【起点大于终点】退出码 101:['slice index starts at 3 but ends at 1']
编译:成功
【str 切在字符中间】退出码 101:["end byte index 2 is not a char boundary; it is inside 'é' (bytes 1..3 of string)"]
编译:成功
运行(退出码 0):
v.get(1..5) = None v.get(1..3) = Some([2, 3]) 编译:成功
运行(退出码 0):
&[()] 长度 1000000,size_of_val = 0 字节(100 万个零大小元素不占内存)
空切片 &[u64] 的指针 0x8:非空 true,对齐到 8: true(指向「一个对齐的悬空地址」,没有内存可读)0x8 是这台机器上 u64 空切片的占位地址,是实现细节,换类型或平台可能不同。
编译:成功
运行(退出码 0):
from_raw_parts(ptr+2, 4) = [3, 4, 5, 6]
chunks(3):[(0, 3), (3, 3), (6, 2)]
windows(3) 的前 3 个窗口:[(0, 3), (1, 3), (2, 3)]
split_first:first = 1,rest 指针偏移 1 长度 7
上面的 (偏移, 长度) 都是以元素为单位,偏移相对于 v 的起点;没有任何元素被复制