如果您从未使用过编译为原生二进制文件的语言,那么您将在Rust中将是可以分发二进制文件的语言。你不必让用户安装指定的运行时环境。

对于node.js、Python、Ruby、PHP、Java还是其它非编译到原生二进制的语言。不得不向外人解释时,为什么要安装一堆东西才能运行。

当你想运行jar你需要安装最新版本的Java来或者使用Python的虚拟环境来运行别人的项目。你不得不在你的计算机上安装一堆可能只用一次的东西。

使用Rust,您可以像c/c++一样分发可执行二进制文件。当然,您可能需要为其它CPU架构和操作系统交叉编译它,但Rust也可以帮助您针对CPU和系统进行交叉编译。

Hello World

你可使用cargo new 初始化您的第一个可Rust项目,例如创建my-app项目运行cargo new my-app即可初始化Rust项目。

默认情况下,cargo new使用二进制应用程序作为模板。但也是在本教程中所使用的模板。如果你需创建一个库,您也可以cargo new --lib库初始化一个库的项目。

执行命令后,您将拥有以下目录结构:

my-app/
├── .git
├── .gitignore
├── Cargo.toml
└── src
    └── main.rs

如果你没有对Rust代码作出任何更改,而是直接cargo run运行项目,项目将会打印一个hello world

cargo run使用指定的目标二进制文件构建您的应用程序。当程序运行后,您的二进制文件已经生成,您可以在./target/debug/my-app找到。

如果您想在不运行的情况下构建您的应用程序,请使用cargo build。Cargo默认使用debug调试配置文件构建你的应用。

使用调试模式构建应用时Rust编译通常速度会更快。它将以牺牲文件大小和性能为代价保留调试信息。

当您准备好发布时你应用时,您将使用构建cargo build --release构建应用程序。你可在目录./target/release/my-app找可发行的二进制可执行文件。

Rust源码

fn main() {
    println!("hello world");
}

现在我们看看Helllo World项目的Rust源码。跟C/C++语言一样main()函数在独立的可执行文件中是必需的。它是应用程序的入口点。

println!()是一个宏,它生成代码以将您的参数打印到标准输出。如果您以前从未使用过宏,它们就像在编译期间生成代码的内联转译器。

对于Rust的宏你可理解为Rust的修饰器,但是这个修饰器并不是在运行时发生的,而是编译的时候已经被展开,你可以使用cargo-expand查看rust宏展开的源码

"Hello, world!"是一个字符串切片,字符串是Rust新用户的第一个主要障碍,我们将在下一篇文章中解决这些问题。

打印字符串变量

fn main() {
    let greeting = "Hello, world!";
    println!(greeting);
}

在上面的代码中。我们首先使用let分配变量greeting="Hello, world!"并尝试打印它。这里的Rust的let关键词相当于JavaScript的const关键字。这是因为Rust的变量默认是不可变的。

const是JavaScript最常用的使用关键字,但是let是Rust最常用使用的关键词。如果您像我们之前所说的那样设置vscode,您就会看到一个错误。

当你尝试使用cargo run编译该rust代码时,它不会编译通过,并给出错误的提示error: format argument must be a string literal

如果您认为这会正常编译并可运行,那是正常的i想法。在大多数语言中,字符串就是字符串。不过在Rust中。请注意查看错误消息。

此消息不仅描述了问题,还向您显示了问题发生的确切位置,并准确告诉您需要做什么来修复它。

println!()需要一个字符串文字作为第一个参数,并支持用变量替换的格式化语法。将您的程序更改为以下Rust代码以修正错误。

fn main() {
    let greeting = "Hello, world!";
    println!("{}", greeting);
}

传递字符串

作为一名经验丰富的程序员,您知道如何编写可重用的代码,并且仅可能将这种复杂的逻辑抽象为可重用的函数。

例如你想把新发现的println!()宏封装一个独立的函数中并尝试为打印的文字添加颜色。你代码将改成以下的样子。

fn greet(target: String) {
    println!("Hello, {}", target);
}
fn main() {
    let greeting = "Hello, world!";
    greet(greeting);
}

直觉上,这看起来是可以通过编译运行的。但是当你使用cargo run运行它运行的时候,Rust将会给出以下提示。

error[E0308]: mismatched types
  --> src/main.rs:16:11
   |
16 |     greet(greeting);
   |           ^^^^^^^^- help: try using a conversion method: `.to_string()`
   |           |
   |           expected struct `String`, found `&str`

For more information about this error, try `rustc --explain E0308`.

虽然rustc的错误消息确实提示你如何解决问题,并让您重新编译运行,但它几乎无法解释真正在发生什么事情。