debug命令_Rust并发花式读取命令行参数

接受命令行参数

和往常一样,让我们​创建一个新项目cargo new。我们将调用我们的项目, minigrep以将其与grep系统上可能已有的工具区分开。

$ cargo new minigrep     Created binary (application) `minigrep` project$ cd minigrep

第一个任务是minigrep接受两个命令行参数:文件名和要搜索的字符串。也就是说,我们希望能够使用cargo run,要搜索的字符串和要搜索的文件的路径来运行程序,如下所示:

$ cargo run searchstring example-filename.txt

目前,由生成的程序cargo new无法处理我们提供的参数。crates.io上的某些现有库可以帮助编写接受命令行参数的程序,但是由于您只是在学习此概念,因此让我们自己实现此功能。

读取参数值

为了能够minigrep读取传递给它的命令行参数的值,我们需要一个Rust标准库中提供的函数 std::env::args。此函数返回给的命令行参数的迭代器minigrep。我们将在第13章中全面介绍迭代器 。现在,您只需要了解有关迭代器的两个细节:迭代器会生成一系列值,并且我们可以collect在迭代器上调用 方法以将其转换为包含向量(如向量)的集合,其中包含迭代器生成的所有元素。

使用清单12-1中的代码,您的minigrep程序可以读取传递给它的所有命令行参数,然后将值收集到向量中。

文件名:src / main.rs

use std::env;fn main() {    let args: Vec = env::args().collect();    println!("{:?}", args);}

清单12-1:将命令行参数收集到向量中并打印

首先,我们std::env使用use语句将模块纳入范围,以便可以使用其args功能。请注意,该std::env::args函数嵌套在两个级别的模块中。正如我们在第7章中讨论的那样,如果所需功能嵌套在多个模块中,则通常将父模块置于作用域而非功能中。这样,我们可以轻松使用中的其他功能std::env。use std::env::args与使用just添加然后调用函数相比,它也没有那么模棱两可args,因为args 很容易将其误认为当前模块中定义的函数。

该args功能和无效的Unicode

请注意,std::env::args如果任何参数包含无效的Unicode ,将会感到恐慌。如果您的程序需要接受包含无效Unicode的参数,请std::env::args_os改用。该函数返回一个迭代器,该迭代器生成OsString值而不是String值。我们之所以选择std::env::args此处为简单起见,因为OsString每个平台的值不同,并且使用起来String比值更复杂。

在的第一行main,我们调用env::args,然后立即使用 collect将该迭代器变成一个包含迭代器产生的所有值的向量。我们可以使用该collect函数来创建多种类型的集合,因此我们显式地注释的类型args以指定我们想要字符串向量。尽管我们很少需要在Rust中注释类型,但这collect是您经常需要注释的功能,因为Rust无法推断您想要的集合类型。

最后,我们使用调试格式化程序来打印矢量:?。让我们尝试先运行不带参数的代码,然后再运行两个参数:

$ cargo run   Compiling minigrep v0.1.0 (file:///projects/minigrep)    Finished dev [unoptimized + debuginfo] target(s) in 0.61s     Running `target/debug/minigrep`["target/debug/minigrep"]
$ cargo run needle haystack   Compiling minigrep v0.1.0 (file:///projects/minigrep)    Finished dev [unoptimized + debuginfo] target(s) in 1.57s     Running `target/debug/minigrep needle haystack`["target/debug/minigrep", "needle", "haystack"]

请注意,向量中的第一个值为"target/debug/minigrep",这是二进制文件的名称。这与C中参数列表的行为匹配,从而使程序可以使用在执行过程中被调用的名称。如果要在消息中打印该名称或根据用于调用程序的命令行别名来更改程序的行为,通常可以方便地访问该程序的名称。但是出于本章的目的,我们将忽略它,仅保存我们需要的两个参数。

将参数值保存在变量中

打印参数向量的值说明该程序能够访问指定为命令行参数的值。现在我们需要将两个参数的值保存在变量中,以便可以在程序的其余部分中使用这些值。我们在清单12-2中进行了处理。

文件名:src / main.rs

use std::env;fn main() {    let args: Vec = env::args().collect();    let query = &args[1];    let filename = &args[2];    println!("Searching for {}", query);    println!("In file {}", filename);}

清单12-2:创建变量以保存查询参数和文件名参数

正如我们看到的那样,在打印矢量时,程序的名称占据了矢量中的第一个值args[0],因此我们从index开始1。第一个参数minigrep是我们要搜索的字符串,因此我们在变量中引用了第一个参数query。第二个参数是文件名,因此我们在变量中引用了第二个参数filename。

我们临时打印这些变量的值,以证明代码按预期工作。让我们再次使用参数test 和运行该程序sample.txt:

$ cargo run test sample.txt   Compiling minigrep v0.1.0 (file:///projects/minigrep)    Finished dev [unoptimized + debuginfo] target(s) in 0.0s     Running `target/debug/minigrep test sample.txt`Searching for testIn file sample.txt

很好,程序正在运行!我们需要的参数值将保存到正确的变量中。稍后,我们将添加一些错误处理来处理某些潜在的错误情况,例如当用户不提供参数时;目前,我们将忽略这种情况,而改为添加文件读取功能。

10c4b06333832366aa565991da1745a2.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值