我有以下内容:
enum SomeType {
VariantA(String),
VariantB(String, i32),
}
fn transform(x: SomeType) -> SomeType {
// very complicated transformation, reusing parts of x in order to produce result:
match x {
SomeType::VariantA(s) => SomeType::VariantB(s, 0),
SomeType::VariantB(s, i) => SomeType::VariantB(s, 2 * i),
}
}
fn main() {
let mut data = vec![
SomeType::VariantA("hello".to_string()),
SomeType::VariantA("bye".to_string()),
SomeType::VariantB("asdf".to_string(), 34),
];
}
我现在想对 data
的每个元素调用 transform
并将结果值存储回 data
。我可以做类似 data.into_iter().map(transform).collect()
的操作,但这会分配一个新的 Vec
。有没有办法就地执行此操作,重新使用分配给 data
的内存? Rust 中曾经有 Vec::map_in_place
,但不久前已被删除。
作为变通方法,我向 SomeType
添加了一个 Dummy
变体,然后执行以下操作:
for x in &mut data {
let original = ::std::mem::replace(x, SomeType::Dummy);
*x = transform(original);
}
这感觉不对,我必须在代码中的其他任何地方处理 SomeType::Dummy
,尽管它永远不应该在此循环之外可见。有更好的方法吗?
最佳答案
您的第一个问题不是map
,而是transform
。
transform
拥有其参数的所有权,而 Vec
拥有其参数的所有权。任何一个都必须放弃,在 Vec
上戳一个洞是个坏主意:如果 transform
发生 panic 怎么办?
因此,最好的解决方法是将 transform
的签名更改为:
fn transform(x: &mut SomeType) { ... }
那么你可以这样做:
for x in &mut data { transform(x) }
其他解决方案会很笨拙,因为它们需要处理 transform
可能会崩溃的事实。
关于rust - 是否可以在不分配新 Vec 的情况下将函数映射到 Vec 上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41832050/