首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在vec上进行映射,并在Rust中使用带有模式匹配的闭包

如何在vec上进行映射,并在Rust中使用带有模式匹配的闭包
EN

Stack Overflow用户
提问于 2016-06-15 23:29:17
回答 4查看 2.7K关注 0票数 3

我想使用map来迭代一个数组,对每个项目做一些事情,并去掉for循环。一个我不理解的错误阻止了我的尝试。我想要实现的是迭代i32的向量,并对它们进行匹配,以将字符串与字符串文字连接起来,然后在最后返回它。

功能:

代码语言:javascript
复制
pub fn convert_to_rainspeak(prime_factors: Vec<i32>) -> String {
    let mut speak = String::new();
    prime_factors.iter().map(|&factor| {
        match factor {
            3 => { speak.push_str("Pling"); },
            5 => { speak.push_str("Plang"); },
            7 => { speak.push_str("Plong"); },
            _ => {}
        }
    }).collect();
    speak
}

fn main() {}

输出:

代码语言:javascript
复制
error[E0282]: type annotations needed
  --> src/main.rs:10:8
   |
10 |     }).collect();
   |        ^^^^^^^ cannot infer type for `B`
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-06-15 23:44:36

Iterator::collect定义为:

代码语言:javascript
复制
fn collect<B>(self) -> B 
where
    B: FromIterator<Self::Item>

也就是说,它返回一个由调用方决定的类型。但是,您完全忽略了输出,因此它无法推断类型。当代码基本上想要使用for时,它滥用了collect

在你的“固定”版本中(这个版本已经被编辑过了,使得这个段落没有任何意义),你在每次迭代中分配一个字符串是非常低效的。此外,除了函数上的那些类型之外,您不需要指定任何显式类型,并且应该接受&[i32]

代码语言:javascript
复制
fn convert_to_rainspeak(prime_factors: &[i32]) -> String {
    prime_factors.iter()
        .map(|&factor| {
            match factor {
                3 => "Pling",
                5 => "Plang",
                7 => "Plong",
                _ => "",
            }
        })
        .collect()
}

fn main() {
    println!("{}", convert_to_rainspeak(&[1, 2, 3, 4, 5]));
}
票数 4
EN

Stack Overflow用户

发布于 2016-06-15 23:41:29

在这种情况下的错误是,编译器无法确定您正在collect到什么类型。如果您将类型注释添加到collect,则它将起作用:

代码语言:javascript
复制
pub fn convert_to_rainspeak(prime_factors:Vec<i32>) -> String{
    let mut speak = String::new();
    prime_factors.iter().map(| &factor| {
        match factor {
            3 => {speak.push_str("Pling");},
            5 => {speak.push_str("Plang");},
            7 => {speak.push_str("Plong");},
            _ => {}
        }
    }).collect::<Vec<_>>();
    speak
}

然而,这真的不是做这件事的惯用方式。您应该改用for

代码语言:javascript
复制
pub fn convert_to_rainspeak(prime_factors:Vec<i32>) -> String {
    let mut speak = String::new();
    for factor in prime_factors.iter() {
        match *factor {
            3 => speak.push_str("Pling"),
            5 => speak.push_str("Plang"),
            7 => speak.push_str("Plong"),
            _ => {}
        }
    }

    speak
}
票数 1
EN

Stack Overflow用户

发布于 2017-08-16 15:59:29

您也可以使用flat_map()而不是map()。这样,如果没有相应的值,您可以映射到Option并返回None而不是空字符串。

代码语言:javascript
复制
fn convert_to_rainspeak(prime_factors: &[i32]) -> String {
    prime_factors
        .iter()
        .flat_map(|&factor| match factor {
            3 => Some("Pling"),
            5 => Some("Plang"),
            7 => Some("Plong"),
            _ => None,
        })
        .collect()
}


fn main() {
    println!("{}", convert_to_rainspeak(&[1, 2, 3, 7]));
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37839702

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档