当前位置:  开发笔记 > 后端 > 正文

是否可以在Vec上映射函数而不分配新的Vec?

如何解决《是否可以在Vec上映射函数而不分配新的Vec?》经验,为你挑选了1个好方法。

我有以下内容:

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),
    ];
}

我现在想调用transform每个元素data并将结果值存回data.现在,我当然可以做类似的事情,data.into_iter().map(transform).collect()但这将分配一个新的Vec.有没有办法在就地执行此操作,重用已分配的内存data?有一次Vec::map_in_place在Rust,但它已被删除了一段时间(我认为在1.4左右).

作为解决方法,我目前添加Dummy-variant SomeType,然后执行以下操作:

for x in &mut data {
    let original = ::std::mem::replace(x, SomeType::Dummy);
    *x = transform(original);
}

但这感觉不对,而且,我必须处理SomeType::Dummy代码中的其他地方,尽管它应该永远不会在这个循环之外可见.有没有更好的方法呢?



1> Matthieu M...:

你的第一个问题不是map,它是transform.

transform取得其论点的所有权,同时Vec拥有其论据.任何一个人都必须给予,并且在这个问题上挖一个洞Vec会是一个坏主意:如果transform恐慌怎么办?


因此,最好的解决方法是将签名更改transform为:

fn transform(x: &mut SomeType) { ... }

那么你可以这样做:

for x in &mut data { transform(x) }

其他解决方案将是笨重的,因为他们将需要处理transform可能恐慌的事实.

推荐阅读
低调pasta_730
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有