0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何使用Rust的标准库和structopt库来处理控制台参数

科技绿洲 来源:TinyZ 作者:TinyZ 2023-09-20 11:13 次阅读

Rust是一种安全、高效的系统编程语言,其标准库以及外部库提供了很多处理控制台参数的方式。在本篇文章中,我们将分别介绍如何使用Rust的标准库处理控制台参数,以及如何使用structopt库处理控制台参数。我们还将介绍如何使用structopt处理复杂结构参数,并且提供相应的示例代码。

处理控制台参数

Rust标准库提供了处理控制台参数的方式,主要基于三个模块:std::env、std::process和std::os::unix。在下面的例子中,我们将展示如何使用这些模块来处理控制台参数:

use std::env;

fn main() {
    let args: Vec< String > = env::args().collect();

    println!("program name is {}", args[0]);

    for arg in args.iter().skip(1) {
        println!("Argument: {}", arg);
        match arg.as_str() {
            "-v" = > println!("version is xxx"),
            "-h" = > println!("Help message"),
            _ = > println!("Unknown argument: {}", arg),
        }
    }
}

在这个例子中,我们使用了std::env::args函数来获取命令行参数,该函数返回一个迭代器,我们需要将其转换为一个向量来方便地处理。接下来,我们使用'iter'函数和命令行参数向量创建一个迭代器。我们执行了'as_str'函数将迭代器值转换为其引用,我们再次使用match语句对参数进行筛选,并显示相应的消息。

在处理控制台参数时,我们通常需要定义一组选项和参数,这些选项和参数可以通过命令行传递给程序。很明显假如我们仅使用标准库提供的API手动解析命令行参数,会非常耗时且麻烦。万幸的是,Rust社区提供了开源的structopt库来帮助我们解析。

使用structopt库处理控制台参数

structopt库提供了一种定义命令行选项和参数的方式,并自动生成解析代码的方法。它使用#[derive]属性来自动生成解析代码,这使得处理控制台参数变得非常简单。

首先,我们需要将structopt库添加到我们的Cargo.toml文件中:

[dependencies]
structopt = "0.3.21"

然后,我们可以使用#[derive]来创建一个结构体,用于定义程序的所有选项和参数。例如,下面的代码定义了一个结构体,其中包含一个字符串参数和两个布尔选项:

use structopt::StructOpt;

#[derive(Debug, StructOpt)]
struct Opt {
    #[structopt(parse(from_os_str))]
    filename: std::path::PathBuf,
    #[structopt(short = "v", long = "verbose")]
    verbose: bool,
    #[structopt(short = "f", long = "force")]
    force: bool,
}

在上面的代码中,我们使用#[derive(StructOpt)]属性来告诉structopt库自动生成解析代码。我们还定义了三个字段:一个路径参数filename,以及两个布尔选项verboseforce。在这里,我们将filename字段标记为parse(from_os_str),以便自动将其转换为PathBuf类型。

接下来,我们可以在程序的main函数中使用Opt::from_args()函数来解析命令行参数并获取我们定义的选项和参数:

use structopt::StructOpt;

#[derive(Debug, StructOpt)]
struct Opt {
    #[structopt(parse(from_os_str))]
    filename: std::path::PathBuf,
    #[structopt(short = "v", long = "verbose")]
    verbose: bool,
    #[structopt(short = "f", long = "force")]
    force: bool,
}

fn main() {
    let args = Opt::from_args();
    println!("{:?}", args);
}

上面的代码将打印出程序的所有选项和参数,例如,如果我们运行./main -v -f /path/to/file.txt,则输出将是Opt { filename: "/path/to/file.txt", verbose: true, force: true }

structopt库还提供了许多其他选项和参数,例如子命令、默认值和验证函数等。有关更多详细信息,请参见官方文档。

structopt处理复杂结构参数

在处理控制台参数时,我们通常需要处理一些复杂的结构参数,例如具有嵌套字段的结构体或向量。在这种情况下,我们可以使用structopt库的#[structopt(flatten)]#[structopt(skip)]属性来解决问题。

首先,让我们考虑一个具有嵌套字段的结构体。例如,下面的代码定义了一个包含名称、年龄和地址的人员结构体,其中地址包含城市、州和国家等嵌套字段:

use structopt::StructOpt;

#[derive(Debug, StructOpt)]
struct Address {
    city: String,
    state: String,
    country: String,
}

#[derive(Debug, StructOpt)]
struct Animal {
    name: String,
    age: u8,
    #[structopt(flatten)]
    address: Address,
}

fn main() {
    let args = Animal::from_args();
    println!("{:?}", args);
}

在上面的代码中,我们使用#[structopt(flatten)]属性将Address结构体的字段展开到Animal结构体中。现在,我们可以将Animal结构体作为命令行参数传递给程序:

$ ./main --name Tom --age 30 --city Chengdu --state Chengdu --country China

上面的命令将创建一个Animal结构体,其中包含名称为Tom、年龄为30岁、地址为北京市、北京市、中国的人员信息。

接下来,让我们考虑一个包含向量字段的结构体。例如,下面的代码定义了一个包含名称、年龄和朋友列表的人员结构体:

use structopt::StructOpt;

#[derive(Debug, StructOpt)]
struct Animal {
    name: String,
    age: u8,
    #[structopt(skip)]
    friends: Vec< String >,
}

fn main() {
    let args = Animal::from_args();
    println!("{:?}", args);
}

在上面的代码中,我们使用#[structopt(skip)]属性将friends字段跳过,因为我们将使用自定义代码来处理它。现在,我们可以将Animal结构体作为命令行参数传递给程序:

$ ./main --name Tom --age 30 --friends Bob --friends Charlie --friends Dave

上面的命令将创建一个Animal结构体,其中包含名称为Tom、年龄为30岁、朋友列表包含Bob、Charlie和Dave的人员信息。我们还需要手动将命令行参数中的朋友列表转换为向量字段。我们可以使用std::iter::FromIterator trait来将命令行参数转换为向量字段:

use structopt::StructOpt;

#[derive(Debug, StructOpt)]
struct Animal {
    name: String,
    age: u8,
    #[structopt(skip)]
    friends: Vec< String >,
}

impl Animal {
    fn from_args() - > Self {
        let mut args = Vec::from_iter(std::env::args());
        let friends = args
            .iter()
            .enumerate()
            .filter_map(|(i, arg)| if i > 0 && args[i - 1] == "--friends" { Some(arg) } else { None })
            .map(|arg| arg.to_owned())
            .collect();
        let args = Animal::clap().get_matches_from(args);
        let name = args.value_of("name").unwrap().to_owned();
        let age = args.value_of("age").unwrap().parse().unwrap();
        Animal { name, age, friends }
    }
}

fn main() {
    let args = Animal::from_args();
    println!("{:?}", args);
}

上面的代码使用std::env::args()函数获取命令行参数,并使用Vec::from_iter()函数将其转换为向量。然后,我们使用filter_map()函数和enumerate()函数来获取命令行参数中的朋友列表。接下来,我们使用std::iter::FromIterator trait将朋友列表转换为向量,并将其存储在friends字段中。最后,我们使用Animal::clap().get_matches_from()函数来解析其他选项和参数,并使用nameage字段创建一个Animal结构体。

结论

在本教程中,我们介绍了如何使用Rust的标准库和structopt库来处理控制台参数。我们讨论了处理简单参数和选项的方法,以及处理复杂结构参数的方法。structopt库提供了一种简单而强大的方式来定义命令行选项和参数,并自动生成解析代码。如果您需要处理控制台参数,那么structopt库是您的最佳选择。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 模块
    +关注

    关注

    7

    文章

    2485

    浏览量

    46533
  • 参数
    +关注

    关注

    11

    文章

    1398

    浏览量

    31472
  • 编程语言
    +关注

    关注

    9

    文章

    1878

    浏览量

    33136
  • 代码
    +关注

    关注

    30

    文章

    4556

    浏览量

    66782
  • Rust
    +关注

    关注

    1

    文章

    223

    浏览量

    6387
收藏 人收藏

    评论

    相关推荐

    ArkTS语言基础类-解析

    统一资源定位符,可以提供找到该资源的路径。 提供常见的[字符串和二进制数据处理]的能力,以及[控制台打印]的相关能力。 字符串编解码功能。 基于Base64的字节编码和解码功能。 提供常见的有理数操作
    发表于 02-20 16:44

    音乐控制台

    音乐控制台
    发表于 05-22 07:55

    ECS 控制台诊断系统

    摘要: 控制台诊断系统,旨在为您提供快速反馈问题的渠道,在降低您的反馈成本的同时,第一时间为您提供解决方案,减少您的损失,给您提供更加平滑的控制台操作体验。当您在操作 ECS控制台 时,可能会
    发表于 12-26 14:03

    终端、虚拟终端、shell、控制台、tty的区别

    今天看到有人问终端和控制台的区别,而且这个问题比较有普遍性,因此想抽出一点时间来解释一下这两个术语的区别。  终端,英文叫做terminal ,通常简称为term ,比如我们在X下的xterm.
    发表于 03-05 13:56

    Linux控制台的JPEG图像显示方法

    查看工具查看图片内容。那么,能不能有办法在控制台下面简单地浏览图像内容呢。实际上,这是完全可以的。在Linux下有一个名为zgv的看图软件就是工作在控制台下的。不过,由于它所使用的底层图形svgalib已经是一个比较“古老”的
    发表于 07-24 06:50

    UART控制台出现问题

    你好,我对UART控制台有点问题,也许你可以帮我。首先,我想打印不同的消息和值到控制台。我使用PIC32 MZ2048 EFH作为应用程序。实际上,我想使用AppIOI控制台。但目前我的设备不支持
    发表于 08-29 12:36

    为什么会有标准文件

    STM32 标准文件详解(以下内容部分引用了火哥资料)先说说为什么会有标准文件?ARM公司设计了Cortex的核心层,放权给芯片厂商,为了解决不同的芯片厂商生产的 Cortex 微
    发表于 08-23 09:24

    Linux终端和控制台的相关资料分享

    关于Linux终端和控制台的基本概念如下:/dev/console即控制台,是与操作系统交互的设备,系统将一些信息直接输出到控制台上。/dev/console根据不同系统的设定可以链接到/dev
    发表于 11-05 08:56

    如何设置LCD作为终端控制台

    屏幕背光节点信息设置 LCD 作为终端控制台LCD简介一些性能参数分辨率由一个一个的像素点组成,常有720P,1080P( 1920 * 1080 ),2K( 2560 * 1440 ),4K( 3840 * 2160 )。以下就是1080P,X=1920,Y=1080
    发表于 12-16 08:26

    STM32标准外设概述

    标题STM32F10X标准外设与文件功能说明一、标准外设概述STM32标准外设之前的版本也
    发表于 01-11 07:29

    如何利用C语言去调用rust静态

    新语言的感觉,要做不少的对接工作。也用过Lua,感觉也差不多。评估学习评估Rust语言时,感觉性能和体积应该都不会有太大的问题。加上语言本身主打的安全性,再结合一些,用来做一些C语言不擅长的动态操作
    发表于 06-21 10:27

    SCVMM 2008 R2管理控制台介绍

    /SCSI硬盘配置等。根据企业生产环境中存在的或是将要上线的业务系统的不同要求,可以创建多个硬件配置文件,从而实现不同类型业务虚拟机的硬件标准化。打开VMM R2的管理员控制台,导航至,并在左上的视图
    发表于 10-24 16:55

    请问是否有任何额外的或sdk来处理ACIM电机?

    有 Nucleo-64 STM32L476RG 和 STEVAL-IPM15B,我计划用 ACIM 电机测试泵的 VFD 和 FOC 驱动,但工作台电机控制是针对永磁电机的!!是否有任何额外的或 sdk 来处理 ACIM 电机
    发表于 12-29 07:40

    McuXpresso的静态和IRQ处理程序问题求解

    我想制作一个静态来处理一些 IRQ 和使用 FreeRTOS 信号量来处理具体处理的主程序。有些事情逃避了我,我不明白如何正确地做到这一点。我试图制作一个静态
    发表于 03-22 08:18

    Rust代码中加载静态时,出现错误 ` rust-lld: error: undefined symbol: malloc `怎么解决?

    我正在 MCUXpresso IDE 中创建一个静态。我正在使用 redlib 在我的代码中导入 ` [i]stdlib.h`。它成功地构建了一个静态。但是,静态中未定义一些标准
    发表于 06-09 08:44