如何从多个迭代器类型中收集? [英] How do I collect from multiple iterator types?

查看:35
本文介绍了如何从多个迭代器类型中收集?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为字符串实现一个新特征,该字符串具有一个将每个字符串的第一个字母大写并取消其余字母大写的函数.我将函数的接口基于 Rust 标准库中的 to_uppercase()to_lowercase().

I am attempting to implement a new trait for a String that has a function that capitalizes the first letter of each String and un-capitalizes the rest. I am basing the function's interface on to_uppercase() and to_lowercase() in the Rust Standard Library.

use std::io;

trait ToCapitalized {
    fn to_capitalized(&self) -> String;
}

impl ToCapitalized for String {
    fn to_capitalized(&self) -> String {
        self.chars().enumerate().map(|(i, c)| {
            match i {
                0 => c.to_uppercase(),
                _ => c.to_lowercase(),
            }
        }).collect()
    }
}

fn main() {
    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer).ok().expect("Unable to read from stdin.");

    println!("{}", buffer.to_capitalized());
}

此代码基于此处给出的建议,但代码已过时并导致多个编译错误.我现在在实现中遇到的唯一问题是以下错误:

This code is based on a suggestion given here, but the code is outdated and causes multiple compilation errors. The only issue I am having with my implementation now is the following error:

src/main.rs:10:13: 13:14 error: match arms have incompatible types [E0308]
src/main.rs:10             match i {
                           ^
src/main.rs:10:13: 13:14 help: run `rustc --explain E0308` to see a detailed explanation
src/main.rs:10:13: 13:14 note: expected type `std::char::ToUppercase`
src/main.rs:10:13: 13:14 note:    found type `std::char::ToLowercase`
src/main.rs:12:22: 12:38 note: match arm with an incompatible type
src/main.rs:12                 _ => c.to_lowercase(),

所以简而言之,fn to_uppercase(&self) 的返回值 ->ToUppercasefn to_lowercase(&self) ->ToLowercase 不能收集在一起,因为地图现在有多种返回类型.

So in short, the return values of fn to_uppercase(&self) -> ToUppercase and fn to_lowercase(&self) -> ToLowercase can't be collected together because the map now has multiple return types.

我尝试将它们强制转换为另一种常见的迭代器类型,例如 BytesChars,但无法收集这些迭代器类型以形成字符串.有什么建议吗?

I've attempted trying to cast them to another common Iterator type such as Bytes and Chars, but these iterator types can't be collected to form a String. Any suggestions?

推荐答案

查看pub fn to_uppercase(&self)的实现后->字符串 这里,我设计了一个解决方案,有点混合了 Dogbert 和 DK. 的解决方案和标准库中给出的实现.它甚至适用于 Unicode!

After looking at the implementation for pub fn to_uppercase(&self) -> String here, I devised a solution that is a bit of a hybrid between Dogbert and DK.'s solutions and the implementation given in the standard library. It even works with Unicode!

fn to_capitalized(&self) -> String {
    match self.len() {
        0 => String::new(),
        _ => {
            let mut s = String::with_capacity(self.len());
            s.extend(self.chars().next().unwrap().to_uppercase());
            s.extend(self.chars().skip(1).flat_map(|c| c.to_lowercase()));
            return s;
        }
    }
}

工作 Rust Playground 示例

为了提高可见性,Shepmaster 的简化和优化解决方案:

For greater visibility, Shepmaster's simplified and optimized solution:

fn to_capitalized(&self) -> String {
    let mut s = String::with_capacity(self.len());
    let mut chars = self.chars(); 

    s.extend(chars.by_ref().take(1).flat_map(|c| c.to_uppercase()));
    s.extend(chars.flat_map(|c| c.to_lowercase()));

    s
}

这篇关于如何从多个迭代器类型中收集?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆