gpt4 book ai didi

arrays - 如何在 Rust 的结构中实现动态二维数组?

转载 作者:行者123 更新时间:2023-12-03 11:29:51 45 4
gpt4 key购买 nike

我是 Rust 的新手,我想实现一个 2D map 。所以我有一个内部宽度、高度和大小未知的数据指针的 map 结构,直到调用一个解析文件然后初始化 map 结构的 load_map 函数。在 C 语言中我会这样做:

struct map {
uint32_t width;
uint32_t height;
uint8_t *data;
};

int load_map(struct map *m)
{
... parse a file and found a map with height=width=8
m->width = 8;
m->height = 8;
// allocate map data using the map size we found
m->data = (uint8_t *)malloc(m->width * m->height);
...
}

在 Rust 中,我不知道如何实现这么简单的事情!这是我失败的尝试:

struct Map<'a> {
width: usize,
height: usize,
data: &'a mut u8
}

fn load_map() -> Map<'static>
{
//code that parse a file and found a map with height=width=8
...

const w:usize = 8;
const h:usize = 8;

//allocate the map data
let mut data = [0;w*h];

// create the map structure
let mut m = Map {
width: w,
height: h,
data: data
};

m
}

fn main() {
let mut m: Map;
m = load_map();
println!("Hello, world! {} {}", m.height, m.width);
}

但是 cargo 不高兴并向我抛出这个错误:

error[E0308]: mismatched types
--> src/main.rs:16:15
|
16 | data: data
| ^^^^ expected `&mut u8`, found array `[{integer}; 64]`

error: aborting due to previous error

我确实理解错误:rust 期望数据的数据类型相同。但我不知道如何实现这一目标。Map 结构是通用的,我们无法在解析文件之前知道数据大小。看来我们应该能够在 init_map 中声明数据字节并将所有权赋予 Map 结构,对吧?但是如何呢?

最佳答案

免责声明:我自己对 Rust 很陌生;我恰好正在研究这个完全相同的问题,因此对它有所了解。可能有比我在这里建议的更好的解决方案或替代方案。

如果在 C 中你有一个指向数组的指针

  uint8_t *data;

malloc 初始化并期望与包含结构具有相同的生命周期,那么你在 Rust 中编写它的方式不是 data: &u8但是:

    data: Box<[u8]>,

这在两个方面与您的尝试不同:

  1. 它有[u8]而不是 u8 , 所以它存储了很多元素而不是一个元素。
  2. 它有Box<...>而不是 &... , 所以它拥有它所指的。

创建一个 Box 将其内容分配到堆上,因此直接对应于 malloc 的使用.在这里,我修改了您的代码以显示此功能并处理了所有警告:

struct Map {
width: usize,
height: usize,
data: Box<[u8]>,
}

fn load_map() -> Map {
const W: usize = 8;
const H: usize = 8;

//allocate the map data
let data = [0;W*H];

// create the map structure
let m = Map {
width: W,
height: H,
data: Box::new(data)
};

m
}

fn main() {
let m: Map = load_map();
println!("Hello, world! {} {} {}", m.height, m.width, m.data[0]);
}

另请注意显式生命周期参数 <'a>'static消失了;现在不需要它们,它们也不会起作用(因为函数分配的东西不能'static,除非你选择leak它)。

但是,这仍然需要一个 const width 和 height 是为了构造数组,一旦从map文件中读取了width和height,这将不起作用。为了解决这个问题,您需要以不同的方式构造数组(或更准确地说,数组切片);一种选择是使用 Vec构造函数(然后将其简化为数组切片,因为您不打算更改长度):

    data: vec![0; w * h].into_boxed_slice(),

关于arrays - 如何在 Rust 的结构中实现动态二维数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63288695/

45 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com