Rust 更新BTreeSet内的结构

Rust 更新BTreeSet内的结构,rust,Rust,我想修改b树集中的结构 我想实现以下目标: 使用std::collections::BTreeSet; #[导出(Eq、PartialEq、Ord、PartialOrd、Debug)] 结构X{ 键:字符串, 瓦尔:选项, } fn main(){ 让mut set:BTreeSet=BTreeSet::new(); 设置。插入(X{ 键:“a”。到_字符串(), 瓦尔:一些(1), }); 设置。插入(X{ 键:“b”。到_字符串(), 瓦尔:一些(1), }); 禁用(&mut set,“a

我想修改
b树集
中的结构

我想实现以下目标:

使用std::collections::BTreeSet;
#[导出(Eq、PartialEq、Ord、PartialOrd、Debug)]
结构X{
键:字符串,
瓦尔:选项,
}
fn main(){
让mut set:BTreeSet=BTreeSet::new();
设置。插入(X{
键:“a”。到_字符串(),
瓦尔:一些(1),
});
设置。插入(X{
键:“b”。到_字符串(),
瓦尔:一些(1),
});
禁用(&mut set,“a”.to_string());
println!(“{:?}”,集合);
}
fn取消通知(集合:&mut BTreeSet,k:String){
对于set.iter()中的mut s{
如果s.key==k{
s、 val=无;
}
}
}
这不起作用,因为
s
不是可变引用

如何完成这样的任务?

b树集中修改对象,使其顺序发生变化(因为这样做会破坏集合的内部结构)是不安全的(就程序逻辑而言)-下面是来自

如果一个项目的修改方式使该项目相对于任何其他项目的顺序(由Ord特征确定)在其位于集合中时发生变化,则这是一种逻辑错误。这通常只能通过单元格、参照单元格、全局状态、I/O或不安全代码实现


我不知道您的确切用例,但由于您似乎正在使用键值对,or可能在这里起作用:它们不允许您出于相同的原因对键进行变异,但与键相关的值可能会发生变异。

如果您想变异生锈不允许您变异的东西,请使用
RefCell
。比如:

并对其进行变异:

fn nonify(set: &mut BTreeSet<X>, k: String) {
    for s in set.iter() {
        if s.key == k {
            *s.val.borrow_mut() = None;
        }
    }
}
fn取消通知(set:&mut BTreeSet,k:String){
对于集合中的s.iter(){
如果s.key==k{
*s、 val.BROW_mut()=无;
}
}
}

但是请注意,作为一个例子,您不应该改变对象的顺序。

如果我们想修改值,使顺序不变,该怎么办?也许排序是由一些关键属性控制的,我们想修改一些附属值。请注意,safe这个词在Rust中有一个非常特殊的含义。更改有序容器中键控值的顺序实际上是安全的,但这是一个逻辑错误。也就是说,这样做不会导致内存损坏或任何不安全的情况,但可能会导致空容器或其他情况。@ksceriath为此,可以使用支持内部可变性的类型(即
单元格
引用单元格
互斥体
,等等),以便在没有可变引用时允许对特定字段进行变异。您还需要确保手动实现该类型的
PartialOrd
/
Ord
,因为派生它将使用所有字段,甚至是您要修改的字段。
struct X {
    key: String,
    val: RefCell<Option<i32>>,
}
X {
    key: "some string".to_owned(),
    val: RefCell::new(Some(1)),
}
fn nonify(set: &mut BTreeSet<X>, k: String) {
    for s in set.iter() {
        if s.key == k {
            *s.val.borrow_mut() = None;
        }
    }
}