You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 09:30:57