Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 如何修改/部分删除BTreeMap中的范围?_Rust - Fatal编程技术网

Rust 如何修改/部分删除BTreeMap中的范围?

Rust 如何修改/部分删除BTreeMap中的范围?,rust,Rust,我正在尝试从一个BTreeMap(其中键是下界,值是上界)构建一个范围集。只要我只是在查找资料,这个方法就可以很好地工作。然而,第一种变异方法让我感到困惑: 如果我想在我的集合中插入一个范围,我需要从尾部到头部的范围的上限检查我的BTreeMap的range,直到所讨论的值低于插入范围的下限,所有包含的范围都应该被删除并合并重叠范围。但是,即使使用当前不稳定的.range\u mut(..),我也找不到删除条目的方法(因为地图仍然是由range借用的) 我用错工具了吗?我可以让它工作吗?如果可以

我正在尝试从一个
BTreeMap
(其中键是下界,值是上界)构建一个
范围集。只要我只是在查找资料,这个方法就可以很好地工作。然而,第一种变异方法让我感到困惑:

如果我想在我的集合中插入一个范围,我需要从尾部到头部的范围的上限检查我的
BTreeMap
range
,直到所讨论的值低于插入范围的下限,所有包含的范围都应该被删除并合并重叠范围。但是,即使使用当前不稳定的
.range\u mut(..)
,我也找不到删除条目的方法(因为地图仍然是由range借用的)

我用错工具了吗?我可以让它工作吗?如果可以,怎么做?我当前的伪代码解决方案(我也使用我自己的
Cut
类型,因为
Bound
s不是
Ord
):

fn插入(&mut self,范围:&range){
用于self.map.range_mut(Cut::Unbounded,range.upper.rev()中的条目{
如果条目.1范围.lower{
删除条目
}否则{
将条目与范围合并
}
}
}

您需要分两次执行此操作,收集要删除的密钥,然后迭代该列表并调用remove

请注意,由于在遍历树时会得到引用,因此必须克隆/复制该键,因为在映射中会有一个对键的引用,这意味着您不能将映射作为可变对象借用

<>这主要是因为内存和排序语义在迭代中间删除条目时有点不正常。在遍历树时删除树中的条目是相当困难的。这是一个映射,这意味着关键点在树中以某种方式排序,这意味着节点可能会旋转其子节点,因此您可能以前访问过您的左子节点,现在突然成为您的当前节点或右子节点。很难知道你在哪里

此外,B-树节点是子节点的列表,当节点需要合并和拆分时,它们具有动态性,在迭代的过程中,这样做更令人头痛。 其中一些原因是由于手动内存语义。键和值存储在节点中,而不是堆上,因此内存将到处弹跳,确保它不会失效是非常重要的。尤其是当用户正在收集对循环中其他位置的树中条目的引用时


编辑:不管可能性如何,事实是迭代器借用了映射,这意味着你不能再借用它来删除东西。如果迭代器返回类似于
条目的内容,这可能会有所不同,但据我所知,没有迭代器存在这种情况。

如果真的不可能一次完成,为什么Java可以这样做?他们的迭代器有一个
.remove()
方法来删除当前条目。我认为应该可以在Rust的std::collection中创建一个类似的选项(可能通过一个产生OccupiedEntryIterator)crate@llogiq迭代器的东西,你可以整理出来,即使它不是有趣的。内存语义要困难得多。Java通过让所有内容都是指针来避免这种情况。考虑一棵树,我有一个A的参考,然后我删除B和一个动作,那现在的参考点是什么?在Java中,答案与堆中的位置相同。在《铁锈》中,答案是“死的记忆”。(这有点不准确,因为Java确实在做一些类似于克隆
Rc
的事情,但却能理解要点)是的,但我们的迭代器可以可变地借用BTree并使用泄漏放大(基本上是交换掉树,因此如果迭代器没有被删除,其他人将看到一个连贯的空树)确保死引用保持这种状态。
fn insert(&mut self, range: &Range) {
    for entry in self.map.range_mut(Cut::Unbounded, range.upper).rev() {
         if entry.1 < range.lower {
             break;
         } else if entry.0 > range.lower {
             delete entry
         } else {
             merge entry with range
         }
     }
}