Golang标准库中提供了功能。flag库是非常基础的功能,在实践上也非常有用,在做命令行交互程序时候必不可少。
package main import "flag" var ( program = flag.String("p", "", "h program to compile/run") outFname = flag.String("o", "", "if specified, write the webassembly binary created by -p here") watFname = flag.String("o-wat", "", "if specified, write the uncompiled webassembly created by -p here") port = flag.String("port", "", "HTTP port to listen on") writeTao = flag.Bool("koan", false, "if true, print the h koan and then exit") writeVersion = flag.Bool("v", false, "if true, print the version of h and then exit") )上述代码会生成一些程序包全局变量,其中将包含命令行参数的值。
在Rust中,常用的命令行解析包是structopt。但是,其工作方式与Golang flag程序包有所不同。structopt会选项加载到结构中,而非全局可变变量。主要因为Rust语言编程实践中,基本上都会避免全局可变的变量。在大多数情况下,带有包的全局变量flag是可以的,但前提是必须在程序真正开始执行其需要做的工作之前将它们写入到程序中。
一个简单示例源自于pahi库源码:
#[derive(Debug, StructOpt)] #[structopt( name = "pa'i", about = "A WebAssembly runtime in Rust meeting the Olin ABI." )] struct Opt { #[structopt(short, long, default_value = "cranelift")] backend: String, #[structopt(short, long)] function_log: bool, #[structopt(short, long)] no_cache: bool, #[structopt()] fname: String, #[structopt(short, long, default_value = "_start")] entrypoint: String, #[structopt()] args: Vec<String>, }
Rust编译器会生成所需的参数解析代码,然后可以使用:
fn main() { let opt = Opt::from_args(); debug!("args: {:?}", opt.args); if opt.backend != "cranelift" { return Err(format!( "wanted backend to be cranelift, got: {}", opt.backend )); }