我想执行以下操作,但是columns
和and_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/