Rust 在结构中实例化2d Vec?
当使用构造函数返回新的struct对象时,我在实例化vec时遇到问题。我尝试过不正确地使用collect的语法,可能会导致大量编译器错误Rust 在结构中实例化2d Vec?,rust,Rust,当使用构造函数返回新的struct对象时,我在实例化vec时遇到问题。我尝试过不正确地使用collect的语法,可能会导致大量编译器错误 fn main() { let level = Level::new(); } struct Level { tiles: Vec<Vec<Tile>> } struct Tile { idx: i32 } impl Level { fn new() -> Level { Le
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++中的类似代码也不正确
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编译器正确地告诉您使用移动值
惯用的方法是使用迭代器,它可以如下所示:
(0..80).map(|_| (0..24).map(|_| Tile::new()).collect()).collect()
如果需要访问索引,可以使用映射闭包参数:
(0..80).map(|x| (0..24).map(|y| Tile::new(x, y)).collect()).collect()
编译器应该自动推断所需的收集结果类型。Vladimir的回答非常好,但是我感觉函数式可能会在这里隐藏错误 你实际上离解决方案不远;问题很简单,您不能在外部循环的每次迭代中重用相同的t2。因此,最简单的转换是在外循环内创建t2:
impl Level {
fn new() -> Level {
Level {
tiles: {
let mut t = Vec::new();
for x in range(0, 80) {
let mut t2 = Vec::new(); // Moved!
for y in range(0, 24) {
t2.push(Tile::new(x, y));
}
t.push(t2);
}
t
}
}
}
你一直在使用什么语法?我会用我刚刚尝试过的内容更新帖子。错误是什么?用errorsWell再次更新帖子,功能风格现在是惯用的方法,也就是说,在将来大部分代码都会这样编写:@VladimirMatveev:我同意,而且它也更整洁、更简洁;然而,我担心这可能比OP的当前代码提高了太多,所以我更愿意在建议改变风格的基础上指出当前的问题是什么,或者我的意思是,让你建议改变风格。我最终使用了Vladimir的解决方案,但你的解决方案帮助我准确地理解了我做错了什么-谢谢!