【问题标题】:Disparity in accessing command-line arguments using nth()使用 nth() 访问命令行参数的差异
【发布时间】:2022-01-05 10:33:04
【问题描述】:

我正在尝试使用 nth() 和 unwrap() 访问命令行参数。使用两种不同的方法。 一个使用函数获取第n个位置的arg,另一个使用参数值初始化变量

use std::env::{args, Args};
fn main() {
    // Approach 1 (using the function) [WORKS]:
    println!("{} {} {}",
      get_nth_arg(1),
      get_nth_arg(2),
      get_nth_arg(3)
    );

    // Approach 2 (DOES NOT WORK (Panics)):
    // Works if run with ..nth(1), ..nth(0), ..nth(0)
    let mut args: Args = args();
    let arg1: String = args.nth(1).unwrap();
    let arg2: String = args.nth(2).unwrap();
    let arg3: String = args.nth(3).unwrap();
    println!("{} {} {}", arg1, arg2, arg3);
}

fn get_nth_arg(n: usize) -> String {
    args().nth(n).unwrap()
}

方法 1 没有问题,而且似乎合乎逻辑。

方法 2 似乎与 nth() 的参数一起工作,按顺序为 1,0,0;但是当 1,2 和 3 作为参数给出时会出现恐慌。

为什么 nth() 需要不同的参数集来为这两种方法工作?

【问题讨论】:

  • .nth() 采用第 n 个 剩余 项。 .next().nth(0) 相同。这能回答你的问题吗?
  • @Coder-256 我没有在这段代码中使用 .next()
  • @ChayimFriedman 我读过这个问题;并了解迭代器在每次调用时都会提前。如果是这种情况,那么用 [1,0,0] 调用的 nth() 不应该适用于方法 1 吗?换句话说,为什么在使用方法1时迭代器没有被推进?
  • @AlbinKC 在方法 11 中,您每次都重新生成 args()。您每次调用都会生成一个不同的迭代器,您可以与其他实例分开推进。

标签: rust command-line-arguments


【解决方案1】:

.nth() 改变它被调用的迭代器。在方法 1 中,这不是问题,因为在每次调用 get_nth_arg 时都会创建一个新的 Args 迭代器。但是在方法 2 中,每个 .nth() 调用都使用相同的迭代器。以下是发生的事情:

let mut args: Args = args();
// At position 0, nothing has been taken from the iterator
let arg1: String = args.nth(1).unwrap(); // take 1 item from the iterator
// At position 1
let arg2: String = args.nth(2).unwrap(); // take 2 items from the *existing* iterator
// At position 3
let arg3: String = args.nth(3).unwrap(); // take 3 items from the *existing* iterator
// At position 6
println!("{} {} {}", arg1, arg2, arg3);

查看此问题的另一种方法是将nth 调用替换为对.next() 的等效调用:

let mut args: Args = args();
let arg1: String = args.next().unwrap();
let _ = args.next().unwrap(); // discard 1 element for nth(2)
let arg2: String = args.next().unwrap();
let _ = args.next().unwrap(); // discard 2 elements for nth(3)
let _ = args.next().unwrap();
let arg3: String = args.next().unwrap();
println!("{} {} {}", arg1, arg2, arg3);

记住,迭代器不记得过去的元素。一旦在迭代器上调用 next,就不能“返回”来获取前一个元素。您可以从迭代器中获取新元素。

【讨论】:

    猜你喜欢
    • 2011-05-15
    • 1970-01-01
    • 2022-01-19
    • 2012-09-01
    • 1970-01-01
    相关资源
    最近更新 更多