🦀 面向 JS 开发人员的 Rust
最初发表于Codegram 的博客
我第一次读到 Rust 🦀 的时候并没有引起我的兴趣。大约两年前,我还是一名 Web 开发者,主要使用 JavaScript,当时我觉得 Rust 不适合我,因为当时它看起来真的很难。
今年年初,我决定开始自学 Rust。这段时间有什么变化吗?我仍然是一名 Web 开发人员,但知道我将能够用 Rust 编写程序,编译为WebAssembly并在浏览器中执行,这点燃了我的学习动力。
在这篇文章中,我将从 JavaScript 开发者的角度介绍 Rust,并进行一些比较。希望这能激励你尝试一下!
什么是 Rust?
Rust 编程语言由 Mozilla 创建,其第一个稳定版本于 2015 年左右发布。它看起来像这样:
fn main() {
println!("Hello, World!");
}
看起来没那么吓人吧?你可能会说它看起来很像 JavaScript,但那只是一个Hello World程序,而且比 JavaScript 要复杂一些!在了解 Rust 的一些特性之前,让我们先把 Rust 放在编程语言的谱系中,如下所示:
编程语言之间有明显的区别:
- 低级:像 C++ 这样可以访问内存管理的语言被认为是低级语言,它们运行速度非常快。但它们也非常不安全,因为很容易弄乱内存,从而导致糟糕的后果!
- 高级:另一方面,像 JavaScript 这样的语言没有对内存的细粒度访问(有垃圾收集器为我们处理所有事情)并且被认为是安全的语言,所以有时它们可能会很慢。
Rust 可以被认为既快速又安全,但它并不是免费的:学习曲线很陡峭,即使对于小例子来说,编译时间也可能有点高。
Rust 主要特性
与任何编程语言一样,有很多内容需要介绍,但我决定重点关注学习和开始使用该语言所必需的四个主题。
类型
1
JavaScript 是一种动态类型语言,我们可以做一些有趣的事情,比如用字符串减去数字wat
,然后得到意想不到的结果。这是可能的,因为它的类型系统并不严格。在 Rust 中,如果你尝试对两个不同类型的数字进行简单的加法运算,就会出现编译错误:
fn main() {
let a: i32 = 42;
let b: f64 1.0;
println!("{}", a + b); // ERROR: a and b are not of the same type.
}
当你开始使用 Rust 工作时,你会遇到很多错误,并且一开始你可能会讨厌这个编译器:
如果你感觉自己像这只狗一样,并且一直在与 Rust 编译器作斗争,别担心!我们都经历过这种情况。
不变性
函数式语言以处理不可变结构而闻名。作为 JavaScript 开发者,我们并非必须使用不可变性,但像Redux和Immutable.js这样的流行库教会了我们这些良好的实践。如今,我们使用let
和const
关键字分别来声明可变变量和不可变变量。
在 Rust 中,我们通常使用来声明变量,默认情况下它们是不可变的。如果我们想使用可变数据,则需要在声明中let
添加关键字,如下所示:mut
fn main() {
let a = 42;
let mut b = 1;
a = 43; // ERROR: a is not mutable
b = 2;
}
所有权
在我看来,这是学习 Rust 最难的概念,因为它与我研究过的其他语言确实不同,但这是使 Rust 快速且安全使用的关键!
当你将一些数据赋值给一个变量时,就意味着该变量拥有这些数据,并且每条数据只能有一个所有者。让我们来看一下实际的例子:
fn main() {
let x = String::from("hello"); // x owns the "hello" string
let a = x; // At this point a owns the "hello" string and x is no longer valid
do_something(x); // ERROR: x cannot be used anymore!
}
Rust 中没有值null
和undefined
值之分,所以我们不能使用没有值的变量。在上例中,当我们将值赋给 时,a
实际上x
是将值从移动x
到 ,a
所以此时x
变量的值是无效的。函数也是如此:
fn main() {
let x = String::from("hello");
do_something(x);
do_other_thing(x); // ERROR: x cannot be used anymore!
}
fn do_something(s: String) {
// Do something with s
}
当我们调用该方法时,do_something
我们将值从 移动x
到s
,即函数接收的参数。执行完函数后,我们返回 ,main
并且x
不再具有有效值。
之前的行为并不总是理想的,这就是 Rust 中我们可以借用东西的原因!如果你不想将值从一个变量移动到另一个变量,可以使用如下引用:
fn main() {
let x = String::from("hello");
do_something(&x);
do_other_thing(&x); // This is ok now because we are not moving the value
}
fn do_something(s: &String) {
// Do something with s
}
当我们处理所有权和借用时,Rust 编译器希望我们表现良好,因此如果我们尝试做错事,它会警告我们:
如果你在了解了所有权和借用之后感到困惑,没关系!你的大脑已经开始处理内存管理了,有时可能会很痛苦。我推荐你观看这个视频,了解更多关于这个主题的知识。
结构体
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 类中的静态方法。
我可以用 Rust 做什么?
首先需要安装 Rust,这非常简单。访问https://rustup.rs/网站下载官方工具链安装程序。它有点类似于JavaScript 常用的nvm项目。
接下来你需要一些库,所以不必从头开始。就像 JavaScript 中的 Node 包一样,Rust 中也需要处理 crate。访问crates.io(官方 crate 仓库),了解更多关于 Rust crate 的信息。
由于 Rust 用途广泛,因此有很多主题可以使用 Rust,并且社区已尽力在不同的网站上跟踪它们:
- www.arewewebyet.org :即使没有像 Ruby on Rails 那样成熟的框架,你也可以构建一些东西!如果你想进行一些 Web 开发,我建议你看看Rocket框架。你甚至可以使用Juniper创建 GraphQL API !
- www.arewegameyet.com:完全掌控内存管理是开发某些游戏的必要条件,因此 Rust 是一个绝佳的选择!如果你对游戏开发感兴趣,我推荐你看看Amethyst游戏引擎。
- www.arewelearningyet.com:另一个目前非常热门的话题是机器学习。Rust 的生态系统目前还不够完善,在机器学习方面可能不如 Python 好,但如果你对这个话题感兴趣,可以看看他们的网站!
最后,如果你正在从事 Web 开发,那你真是太幸运了!你可以创建程序、编译它们,并将其与现有的 JavaScript 代码一起使用。实现这一切的技术是WebAssembly,它现在可以在所有现代浏览器中使用。
如果您想尝试,我建议您阅读官方的Rust 和 WebAssembly 书籍。
结论
Rust 是一门非常酷的语言,你可以用它构建很多东西!如果你和我一样是一名 Web 开发者,你会觉得整个 WebAssembly 主题非常有趣,我希望以后能写一些关于它的文章。
如果你想开始使用 Rust,我建议你查阅官方书籍,并尝试用 Rust 编写一些现有的 JavaScript 程序。很多事情,实践才是关键!
最后,这篇博文的灵感来自于我在JS Coders 聚会活动中的一次演讲,您可以在此处查看幻灯片。
封面照片由Phil Hearing 拍摄
文章来源:https://dev.to/codegram/rust-for-js-developers-1im9