在结构中实例化 2d Vec? [英] Instantiating a 2d Vec in a Struct?

查看:36
本文介绍了在结构中实例化 2d Vec?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用构造函数返回新的结构对象时,我无法实例化 vec.我尝试过的语法(可能不正确地使用了 collect())引发了大量编译器错误.

I'm having trouble instantiating a vec when using a constructor to return a new struct object. The syntax I've tried (using collect() improperly, probably) spat out a ton of compiler errors.

fn main() {
    let level = Level::new();
}

struct Level {
    tiles: Vec<Vec<Tile>>
}

struct Tile {
    idx: i32
}

impl Level {
    fn new() -> Level {
        Level {
            tiles: {
            let mut t = Vec::new();
            let mut t2 = Vec::new();
            for x in range(0, 80) {
                for y in range(0, 24) {
                    t2.push(Tile::new(x, y));
                }
                t.push(t2);
            }
            t
        }
    }
}

impl Tile {
    fn new(x: i32, y: i32) -> Tile {
        Tile { pos: Point { x: x, y: y } }
    }
}

struct Point {
    x: i32,
    y: i32
}

我收到这些错误:

src/game/dungeon/level/mod.rs:47:25: 47:27 error: use of moved value: `t2`
src/game/dungeon/level/mod.rs:47                 t2.push(Tile::new(x, y));
                                                     ^~
src/game/dungeon/level/mod.rs:49:28: 49:30 note: `t2` moved here because it has type `collections::vec::Vec<game::dungeon::level::Tile>`, which is non-copyable
src/game/dungeon/level/mod.rs:49                     t.push(t2);
                                                        ^~
src/game/dungeon/level/mod.rs:49:28: 49:30 error: use of moved value: `t2`
src/game/dungeon/level/mod.rs:49                     t.push(t2);
                                                        ^~
src/game/dungeon/level/mod.rs:49:28: 49:30 note: `t2` moved here because it has type `collections::vec::Vec<game::dungeon::level::Tile>`, which is non-copyable
src/game/dungeon/level/mod.rs:49                     t.push(t2);
                                                        ^~

推荐答案

是的,你做错了.类似的代码在 C/C++ 中也会出错,顺便说一句.

Yes, you're doing it incorrectly. The similar code will also be incorrect in C/C++, BTW.

        let mut t = Vec::new();
        let mut t2 = Vec::new();
        for x in range(0, 80) {
            for y in range(0, 24) {
                t2.push(Tile::new());
            }
            t.push(t2);
        }

问题是,你总是在内循环中推入相同的 t2,然后你总是将相同的 t2 推入 t.后者违反了所有权语义,因此 Rust 编译器正确地告诉您使用移动值.

The problem is, you're always pushing into the same t2 in the inner loop and then you're always pushing the same t2 into t. The latter is a violation of ownership semantics, so Rust compiler correctly tells you about using a moved value.

惯用的方法是使用迭代器,它看起来像这样:

The idiomatic approach is to use iterators and it could look like this:

(0..80).map(|_| (0..24).map(|_| Tile::new()).collect()).collect()

如果你需要访问索引,你可以使用 map() 闭包参数:

If you need to access indices you can use map() closure arguments:

(0..80).map(|x| (0..24).map(|y| Tile::new(x, y)).collect()).collect()

编译器应该自动推导出所需类型的 collect() 结果.

The compiler should automatically deduce the desired type of collect() result.

这篇关于在结构中实例化 2d Vec?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆