Поскольку or_insert()
возвращает изменяемую ссылку на значение - либо существующее, либо вновь вставленное - вы должны иметь возможность вставить None
для columns
в новую запись, а затем безоговорочно перезаписать ее с помощью Some(columns)
:
self.tables
.entry(table_name)
.or_insert(TableInfo {
policies: None,
columns: None,
})
.columns = Some(columns);
Другое, несколько более универсальное c решение заключается в том, чтобы сначала обернуть 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()
, поэтому у нас фактически есть два замыкания, только одно из которых выполняется. Это не обязательно, чтобы этот подход работал, но я думаю, что он делает его более понятным.)