第一次接触 Rust 🦀 时,它并未在我心中掀起波澜。大概在两年前,我还是一名Web 开发者,最常用的编程语言是 JavaScript。彼时 Rust 在我眼中,犹如一座高耸入云的山峰,令人望而生畏。
今年年初,我决定开始自学 Rust。你猜这段时间发生了什么?其实也没发生什么大事,我仍然还是一名 Web 开发者,但我知道了用 Rust 编写程序能够编译成 WebAssembly 在浏览器中运行,于是一股热情的火花便在我心中骤然迸发。
在这篇文章中,我将以 JavaScript 开发者的独特视角,带你领略 Rust 的风采,并娓娓道来两者的异同。我希望我的见闻和感悟,能激励你踏上 Rust 的征程!
Rust 编程语言由 Mozilla 创造,其第一个稳定版本诞生于 2015 年前后。它的庐山真面目是这样的:
fn main() {
println!("Hello, World!");
}
乍一看并不那么可怕吧?你可能会说它几乎和 JavaScript 一模一样,但这只是 hello world 程序,实际上要复杂得多!在我们一探这门语言的特性之前,不妨先将 Rust 置于编程语言谱系之中,如下图所示:
Rust在编程语言谱系中的位置
编程语言之间有着分明的界限:
Rust 集速度与安全于一身,但这需要付出一定的代价:它有着陡峭的学习曲线,即便是一个小小的程序,编译时间也可能颇为漫长。
任何一门编程语言,都有许多需要学习的内容,但我想重点介绍四个主题,精通它们,方能运用 Rust 的神力。
JavaScript 是一门动态类型语言,我们可以做一些有趣的事情,比如从字符串 wat
中减去数字 1
,并获得意想不到的结果[1]。这是因为 JavaScript 的类型系统不够严谨。而在 Rust 中,如果你胆敢对两个不同类型的数字做加法,分分钟就会被编译器逮个正着:
fn main() {
let a: i32 = 42;
let b: f64 = 1.0;
println!("{}", a + b); // 错误:a 和 b 的类型不同
}
当你初涉 Rust 时,你会遇到许多错误,一开始可能会对编译器恨之入骨:
你会和这只狗狗一样,与 Rust 编译器斗智斗勇。不要慌,我们都要经历这个过渡阶段。
函数式编程语言以使用不可变数据结构闻名。作为 JavaScript 开发者,我们并非必须使用不可变性,但像 Redux[2] 和 Immutable.js[3] 这些广受欢迎的库,为我们树立了良好的典范。如今,我们有 let
和 const
关键字,可以分别声明可变和不可变变量。
在 Rust 中,我们只需用 let
来声明变量,默认情况下,它们就是不可变的。如果想让数据可变,需要在声明时冠以 mut
关键字,像这样:
fn main() {
let a = 42;
let mut b = 1;
a = 43; // 错误:a 不可变
b = 2;
}
在我看来,这是学习 Rust 最难掌握的概念,因为它与我接触过的其他语言大相径庭,但这正是 Rust 快速安全的秘诀所在!
当你将数据交给一个变量时,就是在宣告这个变量拥有它,而每一份数据只能被一个变量所有。我们来看一个示例:
fn main() {
let x = String::from("hello"); // x 拥有 "hello" 字符串
let a = x; // 此时 a 获得了 "hello" 的所有权,x 已然失效
do_something(x); // 错误:x 不能再被使用!
}
在 Rust 中,null
和 undefined
是不存在的,因此我们不能使用没有值的变量。在上面的例子中,当我们将 a
赋值给 x
时,实际上是将 x
的值移动到了 a
,此时 x
就失去了它的价值。函数参数的传递,也遵循同样的法则:
fn main() {
let x = String::from("hello");
do_something(x);
do_other_thing(x); // 错误:x 不能再被使用!
}
fn do_something(s: String) {
// 使用 s 做一些事情
}
当我们调用 do_something
函数时,x
的值被移动到了参数 s
。函数执行完毕,返回 main
,x
已然失去了它的意义。
前面的行为并非总是我们所期望的,这就是为什么在 Rust 中,我们可以借用东西!如果你不想将值从一个变量移动到另一个变量,可以使用引用,如下所示:
fn main() {
let x = String::from("hello");
do_something(&x);
do_other_thing(&x); // 现在可以了,因为我们没有移动值
}
fn do_something(s: &String) {
// 使用 s 做一些事情
}
当我们在 Rust 的国度里畅游时,编译器会时刻提醒我们要遵守所有权和借用的规则,如果我们试图做一些违背规则的事情,编译器就会出声警告。
如果你在初次学习所有权和借用后感到很困惑,这很正常!你的大脑正在努力适应内存管理的新概念,这个过程可能会有些不适。我建议你观看这个视频[4],以进一步加深对这个主题的理解。
Rust 虽然不是一门面向对象的语言,但它有一些特性可以模拟面向对象语言的某些行为。在 JavaScript 中使用类时,只需要在同一个地方处理数据和方法。而 Rust 会将数据表示与操作数据的方法优雅地分开,就像这样:
struct Dog {
name: String,
score: i32
}
impl Dog {
fn say_something(self: &Dog) {
println!("Hey, my name is {}... I mean WOOF!", self.name);
}
}
fn main() {
let dog = Dog { name: String::from("Boira"), score: 13 };
dog.say_something();
}
struct Dog
看起来很像一个 JavaScript 对象,但它不是。struct
定义了一些数据的结构,它有两个命名字段:name
和 score
。在 struct
下面,你可以看到一个实现块(简称 impl
)。我们可以在其中声明操作数据的方法,注意,如果我们想将函数与该数据关联起来,需要将 self
作为第一个参数传递。是不是有点像 Python?
如果我们省略 self
值,就声明了一个与任何特定数据都不相关的方法。你可以把它想象成 JavaScript 类中的静态方法[5]。
使用 Rust 之前,需要先安装它,这很简单,只需要访问 https://rustup.rs/ 网站下载官方工具链安装程序。它有点类似于 JavaScript 中常用的 nvm[6] 项目。
接下来,你需要用到一些现成的库,初学者千万不要从零开始撸。就像 JavaScript 中的 NPM 包一样,Rust 也有类似的概念叫 crates。访问 Rust 官方的 crates 注册中心 crates.io[7],探索 Rust crates 的奇妙世界。
Rust 非常通用,可以应用于很多领域,社区在不同的网站上做了很大努力来跟踪这些领域:
最后,如果你正在做 Web 开发,那你很幸运!你可以用 Rust 创建程序,编译它们,并与现有的 JavaScript 代码无缝结合。实现这一点的技术是 WebAssembly[14],现在可以在所有现代浏览器中使用它[15]。
如果你想尝试一下,建议阅读官方的 Rust 和 WebAssembly 电子书[16],开启一段奇妙的探索之旅。
Rust 是一门非常酷的语言,可以用来构建很多有趣的东西!如果你像我一样是一名 Web 开发人员,你会发现 WebAssembly 这个主题非常吸引人,我希望将来自己可以多写一些关于 Rust 的精彩文章。
如果你想尝试使用 Rust,建议查看官方文档[17],并尝试用 Rust 重写部分现有的 JavaScript 程序。实践是通往精通之路的金钥匙!
❝原文链接🔗:https://www.codegram.com/blog/rust-for-js-developers/
[1]
结果: https://www.destroyallsoftware.com/talks/wat
[2]
Redux: https://redux.js.org/
[3]
Immutable.js: https://immutable-js.github.io/immutable-js/
[4]
视频: https://www.youtube.com/watch?v=8M0QfLUDaaA
[5]
静态方法: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static
[6]
nvm: https://github.com/nvm-sh/nvm
[7]
crates.io: http://crates.io
[8]
www.arewewebyet.org: http://www.arewewebyet.org
[9]
Rocket: https://rocket.rs/
[10]
Juniper: https://github.com/graphql-rust/juniper
[11]
www.arewegameyet.com: http://www.arewegameyet.com
[12]
Amethyst: https://amethyst.rs/
[13]
www.arewelearningyet.com: http://www.arewelearningyet.com
[14]
WebAssembly: https://webassembly.org/
[15]
使用它: https://caniuse.com/#search=webassembly
[16]
Rust 和 WebAssembly 电子书: https://rustwasm.github.io/docs/book/
[17]
官方文档: https://doc.rust-lang.org/book/