rust - 不能在互斥的 `Entry` API方法中移动值

标签 rust

我想执行以下操作,但是columnsand_modify(我们知道是互斥的)都移动了,但是编译器不允许这样做。有没有办法仍然使用or_insert API,还是我应该重构为类似Entry的东西,编译器会理解它们是互斥的分支?

self.tables.entry(table_name)
           .and_modify(|e| e.columns = Some(columns))
           .or_insert(TableInfo{
               policies: None,
               columns: Some(columns),
           });

最佳答案

由于or_insert()返回对该值的可变引用-现有值或新插入的值-您应该能够在新条目中为None插入columns,然后无条件地用Some(columns)覆盖它:

self.tables
    .entry(table_name)
    .or_insert(TableInfo {
        policies: None,
        columns: None,
    })
    .columns = Some(columns);

另一种更通用的解决方案是先将columns包装在Option中,然后在两个互斥的闭包中使用Option::take():
let mut columns = Some(columns);
self.tables
    .entry(table_name)
    .and_modify(|t| t.columns = columns.take())
    .or_insert_with(|| TableInfo {
        policy: None,
        columns: columns.take(),
    });

实际上,两个闭包中只有一个可以提取原始值,但是我们知道将只执行其中一个,所以很好。 (我用or_insert()替换了or_insert_with(),所以我们实际上有两个闭包,只执行了其中的一个。这不是使该方法起作用的严格要求,但我认为它更清楚了。)

关于rust - 不能在互斥的 `Entry` API方法中移动值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61020054/

相关文章:

rust - 特征的生命周期作为返回值

rust - 如何使用 Rust 与 Actix web 和 WebSockets 发送服务器事件?

rust - 解决通过引用获取参数的闭包的类型不匹配

rust - 为什么 Rust 借用检查器拒绝这段代码?

memory-management - 如何检测某个类型何时需要调用 'drop'?

rust - 为什么没有为明确实现的类型实现特征?

rust - dyn MyTrait的大小无法在采用self的方法中静态确定。

rust - 如何通过编译器选项覆盖常量?

rust - 无法在 self.attribute 上移出 Box::into_raw 的借用内容

rust - 这个元素 Rust 标记为 "dead code"是必要的吗?