本章主要介绍 rust 的基本输出语句、最常用的 cargo 配置及命令。
新建 crate
cargo init --bin my-hello-world
复制
Cargo.toml 文件是模块配置文件; src/main.rs 是代码文件,包含主体代码逻辑。
目前, src/main.rs 中的代码是:
fn main() {
println!("Hello, world!");
}
复制
这是经典的 hello world 代码段。尝试执行它时,可以在模块根目录( Cargo.toml 所在的目录)中使用命令行 cargo run 命令:
cargo run
复制
此时最后一行显示出的 Hello, world! 就是这个程序的输出。实际上,上述 cargo run 命令包含两步:编译、运行。如果想编译成可以分发的可执行程序,应当使用 cargo build 命令:
cargo build --release
复制
编译成功后,模块的 target/release 目录中会出现 my-hello-world 可执行程序。这个文件可以在没有安装 rust 的环境中执行。
输出语句
回到 main.rs 的代码中,这段代码的基本含义:
// 定义 main 函数(这是程序的主入口)
fn main() {
// 输出字符串内容
println!("Hello, world!");
}
复制
其中 println! 是 rust 的基本输出语句。它可以包含变量:
fn main() {
// 定义一个变量
let s = "LastLeaf";
// 在输出语句中,变量可以用 {} 来嵌入
println!("Hello, {}!", s);
}
复制
上面这段代码会输出 Hello, LastLeaf! 的字样。
需要注意的是,有些类型的变量不可以用上面的方式输出,需要这样:
fn main() {
// 定义一个数组
let s = ["last", "leaf"];
// 在输出语句中,需要使用 {:?} 来嵌入数组
println!("Hello, {:?}!", s);
}
复制
上面的例子中, {:?} 表示的是输出“调试信息”。因为 rust 认为数组并不应该直接展示给用户,所以不能用普通地用 {} 来输出,必须用 {:?} 来输出,而且只应当作为调试信息使用。(上面代码的输出为 Hello, ["last", "leaf"]! ,确实是对用户不友好的。)
实际上,如果只是想输出变量的值用于调试,这种做法更方便:
fn main() {
let s = ["last", "leaf"];
// 快速输出变量的值用于调试
dbg!(&s);
}
复制
这样会以更友好的方式输出变量的当前值。
在实践中,直接用到 println! 语句的机会并不多。通常会用一些第三方模块来辅助打印出更好的输出信息。
在 rust 中引用第三方模块非常方便:开源模块会统一在 crates.io 上发布,可以在网站上查询模块相关信息:
https://crates.io/
在编写后台服务和 GUI 应用的时候,常常需要在代码中打印日志。这种场景下几乎都会用到 log 这个第三方模块。下面就以这个模块为例。
首先,在 Cargo.toml 中的 [dependency] 段下添加模块名和版本号:
[dependencies]
# 引入 log 模块(版本号可以写 1~3 位,这里写两位)
log = "0.4"
# 引入 env_logger 模块(在命令行中配合 log 模块一同使用)
env_logger = "0.8"
复制
在 main.rs 中就可以使用了:
// 引入 log 模块
#[macro_use]
extern crate log;
fn main() {
// 初始化在命令行中的日志输出
env_logger::init();
let s = ["last", "leaf"];
// 输出 info 级别日志,语法类似于 println!
info!("{:?}", s);
// 输出 warn 级别日志
warn!("{:?}", s);
// 输出 error 级别日志
error!("{:?}", s);
}
复制
日志一共有 trace debug info warn error 五个等级。在运行程序之前,需要使用 RUST_LOG 环境变量来指定哪个等级的日志可以被输出出来:
# 非 windows 命令行
export RUST_LOG=warn
# windows 命令行
set RUST_LOG=warn
复制
如上所示,接下来执行 cargo run 的时候就只会输出 warn 和 error 级别的日志了。执行结果类似于:
[时间 WARN my_hello_world] ["last", "leaf"]
[时间 ERROR my_hello_world] ["last", "leaf"]
复制
(注意:改变 Cargo.toml dependency 之后的第一次编译时可能需要下载依赖模块,请注意网络连接。)
Cargo.toml 中还有很多可配置项,之后的文章在必要时详谈。