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

o0lyfsai  于 2023-10-20  发布在  其他
关注(0)|答案(5)|浏览(153)

我只想要一个空格分隔的String的参数变量从std::env::args()获得,我一直在使用fold函数这样创建:

  1. std::env::args()
  2. .fold("".to_string(), |accum, s| accum + &s + " ")

然而,这在末端产生了额外的空间,这是不需要的。我尝试使用truncate函数,但truncate不返回String,只是修改了现有的String,并且这还需要创建中间绑定以便使用Stringlen()调用来定义截断的String应该有多长(我相信,由于Rust当前的词汇借用规则,它本身需要一个中间绑定!)

yqlxgs2m

yqlxgs2m1#

在Rust中,有什么惯用的方法来打印所有命令行参数?

  1. fn main() {
  2. let mut args = std::env::args();
  3. if let Some(arg) = args.next() {
  4. print!("{}", arg);
  5. for arg in args {
  6. print!(" {}", arg);
  7. }
  8. }
  9. }

或者使用Itertools的formatformat_with更好:

  1. use itertools::Itertools; // 0.8.0
  2. fn main() {
  3. println!("{}", std::env::args().format(" "));
  4. }

我只想要一个空格隔开String

  1. fn args() -> String {
  2. let mut result = String::new();
  3. let mut args = std::env::args();
  4. if let Some(arg) = args.next() {
  5. result.push_str(&arg);
  6. for arg in args {
  7. result.push(' ');
  8. result.push_str(&arg);
  9. }
  10. }
  11. result
  12. }
  13. fn main() {
  14. println!("{}", args());
  15. }

  1. fn args() -> String {
  2. let mut result = std::env::args().fold(String::new(), |s, arg| s + &arg + " ");
  3. result.pop();
  4. result
  5. }
  6. fn main() {
  7. println!("{}", args());
  8. }

如果你使用Itertools,你可以使用上面的format/format_with例子和format!宏。
join也很有用:

  1. use itertools::Itertools; // 0.8.0
  2. fn args() -> String {
  3. std::env::args().join(" ")
  4. }
  5. fn main() {
  6. println!("{}", args());
  7. }

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

  1. use itertools::Itertools; // 0.8.0
  2. fn args() -> String {
  3. std::env::args().intersperse(" ".to_string()).collect()
  4. }
  5. fn main() {
  6. println!("{}", args());
  7. }

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

展开查看全部
ih99xse1

ih99xse12#

这里有一个使用迭代器的解决方案,并且不依赖于stdlib
(性能方面,这在发布模式下大放异彩,优化打开[ playground ])

  1. use std::iter::once;
  2. fn join_iter<T>(
  3. mut iter: impl Iterator<Item = T>,
  4. sep: impl Fn(&T) -> T,
  5. ) -> impl Iterator<Item = T> {
  6. iter.next()
  7. .into_iter()
  8. .chain(iter.flat_map(move |s| once(sep(&s)).chain(once(s))))
  9. }
  10. fn examples() {
  11. let iter = [1, 3, 5, 7, 9].iter().cloned();
  12. println!("{:?}", join_iter(iter, |v| v - 1).collect::<Vec<_>>());
  13. // [1, 2, 3, 4, 5, 6, 7, 8, 9]
  14. let iter = ["Hello", "World"].iter().cloned();
  15. let sep = ", ";
  16. println!("{:?}", join_iter(iter, |_| sep).collect::<String>());
  17. // "Hello, World"
  18. }
  19. fn args() -> String {
  20. join_iter(std::env::args(), |_| " ".to_string()).collect()
  21. }
  22. fn main() {
  23. examples();
  24. println!("{}", args());
  25. }
展开查看全部
hmtdttj4

hmtdttj43#

这里有一个替代方案,
我只是想要一个空间分隔String的参数变量从std::env::args()获得

  1. fn args_string() -> String {
  2. let mut out = String::new();
  3. let mut sep = "";
  4. for arg in std::env::args() {
  5. out.push_str(sep);
  6. out.push_str(&*arg);
  7. sep = " ";
  8. }
  9. out
  10. }
  11. pub fn main() {
  12. println!("{}", args_string());
  13. }
cs7cruho

cs7cruho4#

下面是使用fold的版本

  1. fn join<I, T, D>(iter: I, separator: D) -> String
  2. where
  3. T: Display,
  4. D: Display,
  5. I: Iterator<Item = T>,
  6. {
  7. match iter.fold(None, |a:Option<String>, b| {
  8. Some(match a {
  9. None => format!("{}", &b),
  10. Some(mut a) => {
  11. write!(a, "{}{}", separator, b).unwrap();
  12. a
  13. }
  14. })
  15. }) {
  16. None => String::new(),
  17. Some(rval) => rval,
  18. }
  19. }
展开查看全部
vmpqdwk3

vmpqdwk35#

  1. fn main() {
  2. println!("{}", std::env::args().collect::<Vec<_>>().join(" "));
  3. }

相关问题