阅读 223

前端看的Rust教程(4)Hello World

原文:24 days from node.js to Rust

前言

如果你从没和编辑成二进制的语言打过交道,用Rust的时候也不会感到困难,Rust对不同环境下可执行文件的编译做了很好的支持,让程序的移植变得更加轻松,想要了解更多可见:Cross-compilation

Hello world

创建项目

首先我们用cargo new创建一个Rust项目:

cargo new rust-test 复制代码

默认情况下,cargo new会创建一个二进制应用的模板,这也是我们现在所需要的,不过需要留意的是,你也可以通过cargo new --lib命令来创建一个库模板

执行完上面的命令,你会得到这样一个项目:

rust-test/ ├── .git ├── .gitignore ├── Cargo.toml └── src     └── main.rs 复制代码

我们使用的Rust版本是2021,如果你的Cargo.toml文件中edition的值是2018那么就要留意了,本文都是以2021版为准,20182021之间的差异很大(edition类似ECMAScript versions

打包&运行

现在我们可以尝试运行下这个项目,执行cargo run命令:

   $ cargo run    Compiling rust-test v0.1.0 (\rust-test)     Finished dev [unoptimized + debuginfo] target(s) in 1.28s      Running `target\debug\rust-test.exe` Hello, world! 复制代码

cargo run会调用cargo build来打包你的应用,然后运行默认(也可以指定)的二进制文件,运行完这个命令后,会生成好二进制文件,具体的位置是./target/debug/my-app。如果你只是想打包而不不运行,可以执行cargo build命令。默认情况下会生成文件大小、性能等debug信息,当你想要得到release版代码时,可以运行cargo build --release,此时二进制文件的生成目录是./target/release/rust-test

源码分析

下面我们来看下模板中的src/main.rs文件

fn main() {   println!("Hello, world!"); } 复制代码

main()函数在独立可执行文件中是不可或缺的,是程序的入口。println!()是一个宏,用于将参数输出到STDOUT,关于宏我们后面会再详细介绍。"Hello, world!"是一段字符串,这很rust,因为字符串将是学习rust的第一个拦路虎,下面就让我们具体了解下

字符串问题1

首先我们将"Hello, world!"赋值给一个let修饰的变量(rust中采用letconst作为关键词,这点类似JavaScript。不过如果你在JavaScript中使用const的情景,在rust绝大大多数下要使用let

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

此时,如果你的VS Code按照上一篇文章所介绍的那样做好了配置的话,此时你已经能在VS Code中看到错误提示了

image.png

忽略这个提示,试着执行下cargo run试试看:

$ cargo run      Compiling rust-test v0.1.0 (rust-test) error: format argument must be a string literal  --> src\main.rs:3:14   | 3 |     println!(greeting);   |              ^^^^^^^^   | help: you might be missing a string literal to format with   | 3 |     println!("{}", greeting);   |              +++++ error: could not compile `rust-test` due to previous error 复制代码

如果你希望上面的代码能正常运行,那你就是个“正常的”程序员,因为在很多语言里这是行的通的,字符串就是字符串。但是在rust的世界这是不行的。在编写rust代码时要习惯查看报错信息,报错信息不仅会告诉你遇到了什么问题,还会告诉你如何修复。println!()的第一个参数需要是个字符串,并且支持将其用变量格式化,将代码进行如下的改动:

fn main() {   let greeting = "Hello, world!"; +  println!("{}", greeting); } 复制代码

再次执行cargo run,此时运行正确

字符串问题2

对于经验老到的程序员来说,希望可以抽象代码以便进行复用,很可能一开始会写出这样的代码:

fn main() {   greet("World"); } fn greet(target: String) {   println!("Hello, {}", target); } 复制代码

按照以往的编程经验来看,上面这段代码应该没啥问题,但一执行就会发现问题:

$ cargo run      Compiling rust-test v0.1.0 (rust-test) error[E0308]: mismatched types  --> src\main.rs:2:11   | 2 |     greet("World");   |           ^^^^^^^- help: try using a conversion method: `.to_string()`   |           |   |           expected struct `String`, found `&str` For more information about this error, try `rustc --explain E0308`. error: could not compile `rust-test` due to previous error 复制代码

按照提示执行rustc --explain E0308可以得到更多的信息,我们可以通过如下方式进行修复:

fn main() { +    greet("World".to_string()); } fn greet(target: String) {     println!("Hello, {}", target); } 复制代码

具体原因详见 String vs &str in Rust

总结

rust中需要大脑时时刻刻对strings保持警惕,在下文中我们将要介绍所有权(ownership)的概念,这可以帮你解答本文中关于strings的一些疑惑


作者:啦萌朵
链接:https://juejin.cn/post/7038907019960516615


文章分类
前端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐