如何改变Rust中的迭代器元素以反转子串

Squ*_*uit 5 rust

我试图做一个功能,将做到以下几点:
输入:一个String形式的任意长度的"ABC/DEF/GHI"
输出:一个String所有以"/"反转分离子; 在这个例子中,输出将是"cba/fed/ihg".

不仅仅是函数本身,我关心变异函数生成的迭代器背后的一般原理split().

以下是我的最大努力:

fn reverse_string(input: &mut str) -> String {
    input
        .to_string()
        .split('/')
        .map(move |x| x.to_string().rev())
        .collect::<String>()
}
Run Code Online (Sandbox Code Playgroud)

编译器抱怨说

error[E0599]: no method named `rev` found for type `std::string::String` in the current scope
 --> src/main.rs:5:37
  |
5 |         .map(move |x| x.to_string().rev())
  |                                     ^^^
  |
  = note: the method `rev` exists but the following trait bounds were not satisfied:
          `&mut std::string::String : std::iter::Iterator`
          `&mut str : std::iter::Iterator`
Run Code Online (Sandbox Code Playgroud)

这意味着什么,我该如何解决这个问题?

Mat*_* M. 4

如果您正在学习迭代器,我建议您在实际执行之前首先决定您想要做什么。

例如,以下是单个内存分配的示例:

fn reverse_string(input: &str) -> String {
    let mut result = String::with_capacity(input.len());

    for portion in input.split('/') {
        if !result.is_empty() {
            result.push('/');
        }
        for c in portion.chars().rev() {
            result.push(c);
        }
    }

    result
}
Run Code Online (Sandbox Code Playgroud)

迭代器通常专注于不修改其环境的纯方法。不幸的是,这可能会导致效率低下,因为这意味着String向左和向右创建和删除。

现在,从技术上讲,您可以改变环境map(需要一个FnMut),但它只是不受欢迎,因为按照惯例,读者希望它是纯粹的。

因此,当您想要引入额外的状态时,Iterator::fold首选方法是:

fn reverse_string(input: &str) -> String {
    input
        .split('/')
        .fold(
            String::with_capacity(input.len()),
            |mut acc, portion| {
                if !acc.is_empty() {
                    acc.push('/');
                }
                for c in portion.chars().rev() {
                    acc.push(c);
                }
                acc
            }
        )
}
Run Code Online (Sandbox Code Playgroud)

第一个参数是一个累加器,它被传递给闭包的每次调用,然后返回它。最后,在调用结束时fold,返回累加器。

无论是在逻辑上还是在效率上,这都相当于第一个函数,但说实话,我更喜欢这个for版本。