我在结构中有一个列表(sprites: Vec<RefCell<Sprite>>
)
我必须添加并删除对象,添加没有问题,但是无法删除
添加对象
pub fn _clean() {}
fn create_sprite(&mut self, x: f32, y: f32) {
let src_rect = Rect::new(0, 0, 9, 9);
let mut sprite = Sprite::new(0, x, y, src_rect);
self.sprites.push(RefCell::new(sprite));
println!("{}", self.sprites.len());
}
删除对象
let mut pos: usize = 0;
for sprite in &mut self.sprites {
sprite.borrow_mut().x += 1.0;
// collision sprite shoot
if sprite.borrow_mut().x > (self.map.nbr_column as u32 * self.map.tile_wight) as f32 {
println!("shoot out {}", pos);
self.sprites.remove(pos);
//self.remove_sprite(pos);
}
pos += 1;
}
如果我做pop
而不是remove
的同上
我清理了代码以生成可执行的minumun代码
use std::cell::RefCell;
pub struct Sprite {
pub index: usize,
pub x: f32,
pub y: f32,
pub vx: f32,
pub vy: f32,
}
impl Sprite {
pub fn new(index: usize, x: f32, y: f32) -> Sprite {
let mut sprite: Sprite = Sprite {
index: index,
x: x,
y: y,
vx: 0.0,
vy: 0.0,
};
sprite
}
}
pub struct Game {
sprites: Vec<RefCell<Sprite>>,
map: f32,
}
impl Game {
pub fn new() -> Game {
Game {
sprites: vec![],
map: 30.0,
}
}
pub fn update(&mut self) {
let mut pos: usize = 0;
self.sprites.retain(|s| {
// s is &RefCell<Sprite>
s.borrow_mut().x += 1.0;
s.borrow().x <= self.map
});
println!("{}", self.sprites.len());
}
fn create_sprite(&mut self, x: f32, y: f32) {
let mut sprite = Sprite::new(0, x, y);
self.sprites.push(RefCell::new(sprite));
println!("{}", self.sprites.len());
}
pub fn handle_event(&mut self) {
self.create_sprite(10.0, 10.0);
self.create_sprite(20.0, 10.0);
self.create_sprite(30.0, 10.0);
self.create_sprite(40.0, 10.0);
self.create_sprite(50.0, 10.0);
self.create_sprite(60.0, 10.0);
}
}
fn main() {
let mut the_game = Game::new();
the_game.handle_event();
the_game.update();
}
答案 0 :(得分:0)
第let array1 = [{id:"1",title:"Writing"},{id:"2",title:"Singing"},{id:"3",title:"Dance"}];
let array2 = [{tags: "1",title: "USA",type: "text"},{tags: "1,2,3",title: "Japan",type: "image"},{tags: "2,3",title: "Japan",type: "image"}];
let obj = array1.reduce((a,c) => Object.assign(a, {[c.id] : c.title}), {});
array2.forEach(o => o.tags = o.tags.split(",").map(v => obj[v]).join(","));
console.log(array2);
行创建了for sprite in &mut self.sprites
集合的可变借项,该集合跨越整个循环主体。这意味着您无法在循环体内修改集合本身,因为这样做会导致循环无效。
当您尝试调用self.sprites
时,此调用 将导致self.sprites.remove(pos)
之后的所有子画面在内存中向前移动一个。之所以禁止这样做,是因为您当前有一个将要删除的精灵的引用,并且还因为pos
处的精灵将被跳过(pos + 1
调用将其向前移动一个,但是迭代器将移至其后的插槽中。)
Rust提供一种执行循环主体尝试执行的操作的方法:Vec::retain
方法。
remove
这会遍历列表中的每个精灵,然后对其进行更新,然后返回一个条件,当self.sprites.retain(|s| { // s is &RefCell<Sprite>
s.borrow_mut().x += 1.0;
sprite.borrow_mut().x <= (self.map.nbr_column as u32 * self.map.tile_wight) as f32
});
告诉true
保留精灵时,而Vec
告诉false
将其删除。
答案 1 :(得分:0)
感谢您的帮助,此代码有效
...
let map_width = (self.map.nbr_column as u32 * self.map.tile_wight) as f32;
self.sprites.retain(|s| {
// s is &RefCell<Sprite>
s.borrow_mut().x += 1.0;
s.borrow().x <= map_width
});
...