如何获取Rust数组子集的有效可变引用?
Rust:获取可变数组前8字节的可变引用并实现高效非对齐写入
背景与问题
以下读取代码可正常工作,且在AArch64和x86_64架构上能被优化为单条汇编指令:
fn u64_from_low_eight(buf: &[u8; 9]) -> u64 { let bytes: &[u8; size_of::<u64>()] = buf[..size_of::<u64>()].try_into().unwrap(); u64::from_le_bytes(*bytes) }
但尝试用类似写法实现u64的非对齐缓冲区写入时出现异常:
/// Encodes a u64 into 1-9 bytes and returns the number of bytes updated. pub fn encode(value: u64, buf: &mut [u8; 9]) -> usize { let low64: &mut [u8; size_of::<u64>()] = &mut buf[..(size_of::<u64>())].try_into().unwrap(); match value { // FIXME: Change to exclusive ranges once the feature's stabilised. OFFSET0..=OFFSET1_LESS_ONE => { let num = inner_encode::<1>(value, low64); #[cfg(test)] eprintln!("low64: {low64:?}"); #[cfg(test)] eprintln!("buf: {buf:?}"); num }, // 其余分支省略 } }
问题在于low64并未指向原buf的前8字节(实际指向的是副本),导致修改low64后buf的内容完全没有变化。
需要替换low64的定义语句,实现两个目标:
- 正确获取指向
&mut [u8; 9]前8字节的&mut [u8; 8]可变引用 - 该实现可在AArch64和x86_64架构上被优化为单条非对齐写入指令
复现代码与输出
以下代码可复现上述问题,执行后原数组src未被修改:
use std::mem::size_of; fn u64_to_low_eight(value: u64, buf: &mut [u8; 9]) { let low64: &mut [u8; size_of::<u64>()] = &mut buf[..size_of::<u64>()].try_into().unwrap(); *low64 = u64::to_le_bytes(value); dbg!(low64); } fn main() { let mut src: [u8; 9] = [1, 2, 3, 4, 5, 6, 7, 8, 9]; u64_to_low_eight(0x0A_0B_0C_0D_0E_0F_10_11, &mut src); dbg!(src); }
运行输出
Compiling playground v0.0.1 (/playground) Finished dev [unoptimized + debuginfo] target(s) in 0.62s Running `target/debug/playground` [src/main.rs:6] low64 = [ 17, 16, 15, 14, 13, 12, 11, 10, ] [src/main.rs:12] src = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, ]
内容的提问来源于stack exchange,提问作者fadedbee
相关产品推荐
相关产品推荐

