Appearance
4.3 main 函数
在大部分主流操作系统上,一个进程开始执行的时候可以接受一系列的参数,退出的时候也可以返回一个错误码。许多编程语言也因此为 main 函数设计了参数和返回值类型。以 C 语言为例,主函数的原型一般允许定义成以下几种形式:
rust
int main(void);
int main();
int main(int argc, char **argv);
int main(int argc, char *argv[]);
int main(int argc, char **argv, char **env);
Rust 的设计稍微有点不一样,传递参数和返回状态码都由单独的 API 来完成,示例如下:
rust
fn main() {
for arg in std::env::args() {
println!("Arg: {}", arg);
}
std::process::exit(0);
}
编译,执行并携带几个参数,可以看到:
rust
$ test -opt1 opt2 -- opt3
Arg: test
Arg: -opt1
Arg: opt2
Arg: --
Arg: opt3
每个被空格分开的字符串都是一个参数。进程可以在任何时候调用 exit()直接退出,退出时候的错误码由 exit()函数的参数指定。
如果要读取环境变量,可以用 std::env::var()以及 std::env::vars()函数获得。示例如下:
rust
fn main() {
for arg in std::env::args() {
match std::env::var(&arg) {
Ok(val) => println!("{}: {:?}", &arg, val),
Err(e) => println!("couldn't find environment {}, {}", &arg, e),
}
}
println!("All environment varible count {}", std::env::vars().count());
}
var()
函数可以接受一个字符串类型参数,用于查找当前环境变量中是否存在这个名字的环境变量,vars()
函数不携带参数,可以返回所有的环境变量。
此前,Rust 的main
函数只支持无参数、无返回值类型的声明方式,即main
函数的签名固定为:fn main() -> ()
。但是,在引入了?
符号作为错误处理语法糖之后,就变得不那么优雅了,因为?
符号要求当前所在的函数返回的是 Result 类型,这样一来,问号就无法直接在main
函数中使用了。为了解决这个问题,Rust 设计组扩展了main
函数的签名,使它变成了一个泛型函数,这个函数的返回类型可以是任何一个满足 Termination trait 约束的类型,比如()
、Result<(), E>
等类型就是满足这个约束的,它们都可以作为main
函数的返回类型。关于这个问题,可以参见第 33 章。