作者:Michael Salim

原文链接:Rust from 0 to 80% for JavaScript Developers

译文首发链接:zhuanlan.zhihu.com/p/515590234 著作权归作者一切。商业转载请联系作者取得授权,非商业转载请注明出处。

假如你是一名 JavaScript 开发者,这里是一个论题列表,能够协助你快速了解 Rust。有十分多关于 Rust 从零开端的教程。可是假如你现已知道一些 JS 的常识,为什么不比较下它们和 rust 的差异呢?

这些是我希望在你开端学习 Rust 前,要知道的一些差异。

免责声明!

我离十分熟悉 Rust 还有不少的间隔。这些仅仅在我有限的常识里解释这些概念,仅此而已。假如你想要知道细节,你仍是应该去阅览 Rust 的文档。学习rust 去阅览一些 rust 的书也是很好的开端。我的方针是,列出来关于你(还有未来的我)能够疏忽的常识性编程概念,能够专注在作为 JavaScript 开发者现已了解的常识与 rust 的差异。

类型

Rust 是一个类型言语,更像 TypeScript。假如你现已了解 TypeScript,相信你去学 rust 会有更好的体验。

有许多语法,rust 和 TS 是相同的,例如 variable_name: Type。

snake_case

习气它吧。

这些符号是什么?

问号(?)

你会在许多方程调用后边看到 ? :my_function()?

这个可不是可选链。这个是处理能够过错的函数的过错处理语法糖(译者:magic 翻译为语法糖)。当处理异步函数时,会许多用到这个语法。后边也会具体讲相关的内容。

(译者注:rust 许多吸收了函数式编程的精华,内置了十分强壮的容器系统,每个函数都回来一个或许成功或许失利的容器。不需求了解任何函数式编程的内容,只需习气这种写法就好了。成本是,每个函数都要自己处理好成功做什么,失利做什么。 rust 的过错处理机制十分好,可是需求每个开发自己完成自己的过错处理机制,这一点在初学时能够先疏忽,有个出名的 anyhow 包,用起来就好了。)

方程后边的感叹号(!)

例如:println!(“{:?}”, my_variable);

这个符号阐明 println 是一个宏。JS 没有这样的语法。宏时用代码在编译时生成代码的技能。你能够认为是一系列的语法糖。运用这些宏就好了。

& 符号

例如:&your_variable

这个符号取得了这个变量的引用。假如你用过 C 或许 go,应该见过这个符号。

语法

  1. 分号 ; 在每个代码行最后,必须写,这一点和 JS 不相同。
  2. 破例:假如有一行没有写分号,是 return 的语法糖。
  3. 函数声明的语法和 JS/TS 不太相同。习气就好了
fn foo(num: i32) -> i32 {
  3 // 见第二点
  // 或许
  // return 3;
}
  1. 装修器语法也不相同。被称为 Attributes。

这些关键字是什么?

struct

这个相当于一个 JSON 目标。(当然这么说是为了更契合 JavaScript 的感觉,更细节请参阅官方文档。可是初期这么了解没什么问题。)

// TypeScript
type Person = {
  firstName: string;
  lastName: string;
};
// Rust
struct Person {
    first_name: String,
    last_name: String,
}

trait

能够了解为 interface。(译者注,TypeScript 的 interface 和 trait 十分像,并且由于 TypeScript 的interface 自身支撑鸭子类型,实践上能够比 trait 的限制更小,也就是说,实践上两者能够规划为有相当相同的编程范式,当然条件是假如你乐意。)

impl

trait 的完成。和 JS 里比较附近的概念是 class(译者:里的 implement)。 这个语法是 trait 和 类型的桥梁。我还没用过。

enum

和 TypeScript 的 enum 相似。可是你能够往里面存数据。在异步代码里是一个十分重要的概念,十分强壮。

Console.log

很遗憾,比 JS 的杂乱许多。更像其他言语的 printf。

println!("{:?}", my_variable);

库/依靠

运用 Cargo.toml, 而不是 package.json。你需求手动添加依靠,而不是运用像 yarn add 这样的指令。

文档。

比如:

[dependencies]
chrono = "0.4"
egg-mode = "0.16.0"

Importing(外部依靠)

Rust 有模块系统。(译者注:JS有一个相同好的就好了。)和 JS 的区别十分大。

更像姓名空间。下面是一个引进依靠的比如:

use rocket::serde::{json::Json, Deserialize, Serialize};

use 相当于 js 的 import。

rocket 是包的姓名。

:: 获取模块的符号。

serde 模块的姓名

{json::Json, Deserialize, Serialize} 引进模块内具体的东西。

一些更多的语法:

use chrono::prelude::*;
use rusqlite::Result;

Importing 本地文件

最好的解释文档:File hierarchy – Rust By Example

运用 mod 去告诉编译器你想引进的文件夹或许文件。

然后运用 use 去引进你想引进的内容。也有不写 mod 的办法,需求运用 crate 前缀。(译者注:crate 相当于我们一般在 tsconfig 或许 vite 里设置的 @ 的快捷链接,相当于从根目录开端寻址。)

use crate::your_file_or_module;

注意:mod.rs 是一个特别的文件名相当于 index.js

更多的比如请看上面的链接。(译者注:rust 这一块十分杂乱,由于类的 public private 等访问限制也是在这一层做的,和 js 不相同,rust 能够在一个文件内有多个模块。当这些规矩混在一起时,有十分多的或许性。可是一般来说,形成自己的习气仅仅时间的问题。初学 rust 会觉得它没有 oop 的规划,可是实践上它不是没有,而是把 oop 的规划四散到例如模块管理,trait 完成、装修器、宏等当地。rust 的表现力十分强,假如你喜欢言语的表现力,rust 绝对会让你爱不释手。并且 rust 的代码比 c++ 好读太多了。)

Const 与 let

(译者注:与 js 完全不相同,这一点要谨记在心)

在 JavaScript 里运用 const 去声明一个不行变变量。(关于杂乱类型,表明地址不行变)

在 Rust 里,这一点实践是由 let 完成的。并且不行变是默许的状况。假如你想要可变,你需求加上 mut 关键字。const 是为了给实践常量(表明你不能够从其他变量核算取得这个值)运用的。

let immutable_variable = ...;
let mut mutable_variable = ...;
const MY_CONSTANT = "CONSTANT";

库文档

假如你在 github 上找不到这个链接,你能够在 crates.io 的对应页面找:

JavaScript 开发者的Rust 教程:从 0 到 80%[译文]

编辑

添加图片注释,不超越 140 字(可选)

JavaScript 开发者的Rust 教程:从 0 到 80%[译文]

编辑

添加图片注释,不超越 140 字(可选)

异步

到目前为止,rust 最让我利诱的两个概念是 futures 和 ownership。假如你想要了解这些概念,我建议你找专门的文档好好学习他们。这里我们先谈 future。

Future 和 Promise 有点像。可是不像 JS,Rust 有一个关于 promise/future 的成果类型 Result。这个类型能够接收过错的范型(我希望 JS 也有这个类型,译者注:我也希望)。你也能够在不运用 future 的时候用 Result。

履行(或许消费)future

原生的库由于太裸了,并不能直接运用,你需求运用外部的库(有点像 JS 的 bluebird)。你需求一个履行器去履行 future。我引荐 github.com/tokio-rs/to… ,请具体阅览它的文档。

.await 去 await 一个方程

async_function().await; 这是一个有趣的语法,不是么?你不需求像 JS 相同加括号。

处理 Result

这是十分重要的一个概念。Rust 是一个安全的言语,意味着你要处理一切的事情(译者注:许多人认为 rust 是一个安全的言语是 rust 帮你处理了安全,这种了解是不对的,仍是开发者处理的,rust 暴漏了更多问题给开发者,在编写时要去处理。)。是的,不像 JS,一切的过错问题(译者注:和 TypeScript 有相似的当地,可是比 TypeScript 要更严厉,尤其是内存方面。特别希望 TypeScript 也能出一个生命周期的机制,处理变量深浅拷贝的问题太让人郁闷了)。

Result 枚举类型有两个特点,一个是 Ok,一个是 Err。假如 future 成功了,回来 Ok,不然回来 Err。

一个比如:

let f = File::open("hello.txt");
let mut f = match f {
    Ok(file) => file,
    Err(e) => return Err(e),
};

上面这个比如用了 Rust 反常强壮的模式识别(译者注:太强壮了,以至于一切的言语几乎都在 2022年开端抄这个特性)。

这么写太麻烦了,有两种通用的办法简化它:

  1. 运用 .unwrap()

比如:let my_value = async_function().await.unwrap();

这个写法会在成功时取得值,失利时 panic。

运用这个写法,你最好确定必定不会有问题。

  1. 运用 ? 语法

这个会把 error 传递下去。所以你的函数也要传递 error(一般通过 Result 或许 Option)

更多的比如请参阅。

Ownership 和 References

你听说过 rust,应该听说过 borrow checker 吧?我在这不会说太多。这是这里最难的部分,由于这是 rust 独有的东西。假如你以前从来没有处理过 references,这一块对你会十分难。

可是,感谢 rust 的文档:简单说,好好读4.1,4.2,4.3。(译者注:这一块一开端不了解是无所谓的,这一块必须通过时间,和写的代码多了去了解,光看是没意义的。)

嗯,就这些!

这个列表比我想象的还要短。希望对你的 rust 之旅有协助。