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

Rust中如何将二维数组转换为一维引用(类似C/C++连续数组)

在Rust中实现二维数组转连续切片(模拟C/C++连续数组效果)

Rust中固定大小的二维数组(如[[T; N]; M])内存布局和C/C++完全一致,都是连续存储的。你之前的unsafe写法可以优化得更可靠,同时也有安全的实现方案:

更稳妥的Unsafe实现

直接利用二维数组的连续布局,避免多余的addr()转换,写法更简洁且可靠:

use std::slice;

let mut a = [[0u8; 10]; 10];
let a_ref = unsafe {
    // 将二维数组的指针转为元素类型指针,长度为总元素数
    slice::from_raw_parts_mut(a.as_mut_ptr() as *mut u8, 10 * 10)
};
a_ref.iter().for_each(|i| print!("{i} "));

这里a.as_mut_ptr()返回指向第一个子数组的指针,由于子数组本身是连续存储的,整个二维数组的内存是连续的,因此将其转为元素类型指针是安全的,只要保证长度计算正确(行数×列数),且切片生命周期与原数组一致。

安全实现(无需Unsafe)

如果不想手动写unsafe代码,可以使用bytemuck库(它会在编译期验证类型布局的兼容性):

  1. 先在Cargo.toml中添加依赖:
[dependencies]
bytemuck = "1.13"
  1. 代码实现:
use bytemuck::cast_slice_mut;

let mut a = [[0u8; 10]; 10];
let a_ref = cast_slice_mut(&mut a);
a_ref.iter().for_each(|i| print!("{i} "));

cast_slice_mut会自动验证[[u8;10];10]和[u8]的内存布局兼容性,确保转换安全,无需手动处理指针。

和C实现的对比

你的C代码中int *pA = a[0]本质是取第一个子数组的首元素指针,对应到Rust中就是&mut a[0][0] as *mut u8,而我们上面的a.as_mut_ptr() as *mut u8和这个逻辑等价,因为子数组的首地址就是二维数组的首地址。

内容的提问来源于stack exchange,提问作者Joshua

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 19:00:53