在Rust中打印用空格分隔的迭代器的惯用方式是什么?

Har*_*ock 8 rust

我只想要一个空格String,这些空格与从中获取的参数变量分开,该变量std::env::args()是我一直使用以下fold函数创建的:

std::env::args()
    .fold("".to_string(), |accum, s| accum + &s + " ")
Run Code Online (Sandbox Code Playgroud)

然而,这在末端处产生了多余的空间,这是不需要的。我尝试使用该truncate函数,但未truncate返回a String,仅修改了现存的String,并且这将需要创建一个中间绑定,以便使用Stringlen()调用来定义被截断的长度String(这本身将需要我相信,由于Rust的当前词汇借用规则,中间绑定必不可少!)

She*_*ter 7

在Rust中打印所有命令行参数的惯用方式是什么?

fn main() {
    let mut args = std::env::args();

    if let Some(arg) = args.next() {
        print!("{}", arg);

        for arg in args {
            print!(" {}", arg);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

或者使用Itertools更好format

use itertools::Itertools; // 0.8.0

fn main() {
    println!("{}", std::env::args().format(" "));
}
Run Code Online (Sandbox Code Playgroud)

我只想要一个空格 String

fn args() -> String {
    let mut result = String::new();
    let mut args = std::env::args();

    if let Some(arg) = args.next() {
        result.push_str(&arg);

        for arg in args {
            result.push(' ');
            result.push_str(&arg);
        }
    }

    result
}

fn main() {
    println!("{}", args());
}
Run Code Online (Sandbox Code Playgroud)

要么

fn args() -> String {
    let mut result = std::env::args().fold(String::new(), |s, arg| s + &arg + " ");
    result.pop();
    result
}

fn main() {
    println!("{}", args());
}
Run Code Online (Sandbox Code Playgroud)

如果您使用Itertools,join则很有用:

use itertools::Itertools; // 0.8.0

fn args() -> String {
    std::env::args().join(" ")
}

fn main() {
    println!("{}", args());
}
Run Code Online (Sandbox Code Playgroud)

在其他情况下,您可能需要使用intersperse

use itertools::Itertools; // 0.8.0

fn args() -> String {
    std::env::args().intersperse(" ".to_string()).collect()
}

fn main() {
    println!("{}", args());
}
Run Code Online (Sandbox Code Playgroud)

请注意,这不如其他选择有效,String因为每次迭代都将其克隆。

  • 如果将“ for”循环放入“ if let”内部,则无需使用“ fuse”。 (3认同)
  • 使用`itertools`,您可以执行`std :: env :: args()。join(“”)`(感谢OP和@bluss作为问题注释的提示)。 (2认同)

Mir*_*clx 6

这是一个带有迭代器和零非 stdlib 依赖项的解决方案

(性能方面,这在发布模式下表现出色,并且开启了优化 [ playground ])

use std::iter::once;

fn join_iter<T>(
    mut iter: impl Iterator<Item = T>,
    sep: impl Fn(&T) -> T,
) -> impl Iterator<Item = T> {
    iter.next()
        .into_iter()
        .chain(iter.flat_map(move |s| once(sep(&s)).chain(once(s))))
}

fn examples() {
    let iter = [1, 3, 5, 7, 9].iter().cloned();
    println!("{:?}", join_iter(iter, |v| v - 1).collect::<Vec<_>>());
    // [1, 2, 3, 4, 5, 6, 7, 8, 9]

    let iter = ["Hello", "World"].iter().cloned();
    let sep = ", ";
    println!("{:?}", join_iter(iter, |_| sep).collect::<String>());
    // "Hello, World"
}

fn args() -> String {
    join_iter(std::env::args(), |_| " ".to_string()).collect()
}

fn main() {
    examples();

    println!("{}", args());
}
Run Code Online (Sandbox Code Playgroud)