如何获取非功能代码块的变量所有权

时间:2016-07-06 21:45:23

标签: rust

for tower in &mut game.towers {
    tower.towers_attack(&mut game)
};

给出cannot borrow game as mutable more than once at a time [E0499]

我的代码正在运行,但我正在重构它以使其更有意义。

工作是什么(主要注意事项是,在游戏对象上可变地循环两次很好,但这是因为功能拥有“游戏”的所有权?)

impl Attack for Game {
    fn towers_attack(&mut self) {
        for tower in &mut self.towers {
            tower.attacked = false;
            if tower.hp.is_positive() {
                for creep in &mut self.lane_creeps {
                    if tower.position.distance_between(creep.position) < 12.0 &&
                       creep.side != tower.side && !tower.attacked {
                        creep.hp -= tower.attack_damage as i32;
                        tower.attacked = true;
                        break;
                    }
                }
            }
        }
    }
}

game.towers_attack();

将第一个循环移到函数外部并在tower而不是game.tower上实现会导致问题。

我很困惑自己,我相信我只需要将game的所有权归还for tower in &mut game.towers { tower.towers_attack(&mut game) };然后在退出时归还所有权,因此如果我明确授予所有权,则不会发生借款,但是,我不确定这是否可行或有意义。

towers_attack功能

impl TowerAttack for Tower {
    fn towers_attack(&mut self, game: &mut Game) {
        self.attacked = false;
        if self.hp.is_positive() {
            for creep in &mut game.lane_creeps {
                if self.position.distance_between(creep.position) < 12.0 &&
                   creep.side != self.side && !self.attacked {
                    creep.hp -= self.attack_damage as i32;
                    self.attacked = true;
                    break;
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:4)

new CheckboxCell(true, false)

Rust会阻止此调用,因为public Widget test() { DataGrid<DatagridType> grid = new DataGrid<DatagridType>(); final MultiSelectionModel<DatagridType> selectionModel = new MultiSelectionModel<DatagridType>(new ProvidesKey<DatagridType>() { @Override public Integer getKey(DatagridType item) { return item.getRowId(); } }); grid.setSelectionModel(selectionModel, DefaultSelectionEventManager.<DatagridType> createCheckboxManager()); selectionModel.addSelectionChangeHandler(new Handler() { @Override public void onSelectionChange(SelectionChangeEvent event) { Window.alert(selectionModel.getSelectedSet().toString()); } }); grid.addColumn(new Column<DatagridType, Boolean>(new CheckboxCell(true, false)) { @Override public Boolean getValue(DatagridType object) { return selectionModel.isSelected(object); } @Override public void render(Context context, DatagridType object, SafeHtmlBuilder sb) { if(object.isActive()) super.render(context, object, sb); } }, "Select"); TextColumn<DatagridType> nameColumn = new TextColumn<DatagridType>() { @Override public String getValue(DatagridType object) { return object.getEmpName(); } }; TextColumn<DatagridType> idColumn = new TextColumn<DatagridType>() { @Override public String getValue(DatagridType object) { return Integer.toString(object.getEmpId()); } }; TextColumn<DatagridType> statusColumn = new TextColumn<DatagridType>() { @Override public String getValue(DatagridType object) { return object.isActive() ? "Active" : "In Acticve"; } }; grid.addColumn(nameColumn, "EMP Name"); grid.addColumn(idColumn, "EMP ID"); grid.addColumn(statusColumn, "Status"); List<DatagridType> values = new ArrayList<DatagridType>(); values.add(new DatagridType(0, "ABC", 1001, true)); values.add(new DatagridType(1, "ABC", 1001, false)); values.add(new DatagridType(2, "AAA", 1002, true)); values.add(new DatagridType(3, "AAA", 1002, false)); values.add(new DatagridType(4, "BBB", 1003, true)); values.add(new DatagridType(5, "BBB", 1003, false)); grid.setRowData(values); grid.setHeight("500px"); Window.alert("Done"); return grid; } private class DatagridType { private int rowId; private String empName; private int empId; private boolean active; public DatagridType(int rowId, String empName, int empId, boolean active) { this.rowId = rowId; this.empName = empName; this.empId = empId; this.active = active; } public int getRowId() { return rowId; } public String getEmpName() { return empName; } public int getEmpId() { return empId; } public boolean isActive() { return active; } @Override public String toString() { return Integer.toString(rowId); } } 的实现可能

for tower in &mut game.towers {
    tower.towers_attack(&mut game)
}

或者

towers_attack

导致向量被重新分配,因此迭代器无效,这将导致坏事发生。

相反,将所需的项目子集传递给fn towers_attack(game: &mut Game) { game.towers.clear() } 。例如:

fn towers_attack(game: &mut Game) {
    game.towers.push(...)
}
  

我只需要将游戏的所有权归为towers_attack

始终将表达式的所有权转移到fn towers_attack(lane_creeps: &mut Vec<Creeps>) { ... } 循环。在这种情况下,您将可变参考的所有权传递给for tower in &mut game.towers { tower.towers_attack(&mut game) };

  

然后在退出时返回所有权

没有办法做到这一点; for循环不会返回任何内容。