JavaScript程序员15分钟掌握80%的Rust语言知识

如果你是一位JavaScript程序员,本文将带领你迅速的理解Rust这种编程语言的诸多语言知识。网上有很多关于Rust的零基础教程,但是,既然你已经是一位程序员了,为什么不跟自己已经熟悉的编程语言对比一下呢?

在你动手研究Rust之前,请听我讲一下它与JavaScript之间的相同和差异,我的介绍会很简洁。

免责声明

我绝对不敢说对Rust很精通。我尽量尽我所知。Rust本身的文档很丰富很广泛,如果你想深入研究,可以参考这些知识。我的目的就是列出一些关键点,一些在编程中最常遇到的概念、知识,焦距于与JavaScript中你已经掌握的知识的对比。这样可以避免你重复学习,节省时间。

变量类型

Rust是一种类型化的编程语言,非常接近TypeScript语言。如果了解TypeScript,对掌握Rust语言会有很大帮助。

基本上它的定义语法都是 (variable_name: Type) 这样的!

snake_case

Yep, no getting around it.

这些符号的作用?

1. 问号 (?)

你会在一些函数调用的后面看到一个?: my_function()?;.

这个问号并不是表示可有可无。 它是针对会出现错误的函数的异常捕捉处理。后面我会细聊。

参考文档

2. 函数中的叹号 (!)

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

它表示这是一个宏。JavaScript没有跟这个类似的东西。宏是一种用写一些代码输出另外一些代码的东西。你可以把它理解为一种语法糖。用法就像上面的例子那样。

3. 符号&

例子: &your_variable

获取引用。如果你用低级语言,比如C语言,相信你会理解这个。后面细聊。

语法

  1. 每行代码的结尾的分号 (;) 是必须的
  2. 例外:函数里最后一行代码的分号 (;) 可省略。这种情况下, 这是返回此行代码运行结果的简写。
  3. Rust函数的语法更JavaScript稍微有些不同。总体来说问题不大。
fn foo(num: i32) -> i32 {
  3 // See no.2
  // or
  // return 3;
}
  1. Decorator syntax also different. It’s also called Attributes.

一些关键词

struct

是一种 JSON 对象。 (好吧,可能会复杂一些,请看文档吧)

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

trait

接口

impl

trait的接口实现跟JavaScript里最接近的是类(Classes)。

enum

跟Typescript里的枚举enums一个路数。你可以在里面存储一些数据。在学习 async 的时候它是一个非常重要的概念。

Console.log

JavaScript里不难理解。 更像是C语言里的 printf

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

代码库/关联依赖

Use Cargo.toml instead of package.json. You’ll want to add them manually (instead of using a command like yarn add)

Documentation

Example:

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

Importing

Rust has modules. It’s quite different from JS but basically:

They’re sort of like namespaces. Here’s a breakdown on importing a dependency

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

use – use this instead of import

rocket – this is the package name

:: – accessing a module

serde – the module name

{json::Json, Deserialize, Serialize} – things to actually import

Some more syntax:

use chrono::prelude::*;

use rusqlite::Result;

Importing from local files

Best explanation: https://doc.rust-lang.org/rust-by-example/mod/split.html

Use mod to the path/file you want to import to make the compiler include the module.

Then use to import it. Note: mod automatically imports it too. In this case, you will need prefix it with crate.

Example:

use crate::your_file_or_module;

Note: mod.rs is a special filename which acts like index.js

See the link above for examples.

Const vs let

In JavaScript you’d use const most of the time because it’s immutable.

In Rust, you’ll want to use let instead. This is immutable by default. If you want it to be mutable, use mut keyword. const are reserved for actual constants (so you can’t calculate the value from another variable)

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

Library Documentation

If the Github repo doesn’t link to the documentation page, you can probably get to it like this:

Asynchronous

By far, the 2 most confusing topic are futures and ownership. I would recommend reading a more comprehensive documentation for these. Let’s talk about futures first.

Future is like a Promise. Unlike JS, Rust has a type for the result of the promise/future called Result. It also accepts the error type on the generics (I wish JS has this). You can also use Result on its own without future.

Executing (or “consuming”) Future

The standard library is quite barebones so you’ll need to import something else (Think bluebird for JS). You need an executor to run a future. I recommend using https://github.com/tokio-rs/tokio and reading their documentation.

.await to await a function

async_function().await; Interesting syntax, yeah? Actually quite nice since you don’t have to wrap it with brackets like in JS.

Handling Result

This is another important one. Rust is safe so you’ll need to handle everything. Yes, all error cases unlike JS!

The Result enum has Ok and Err. If the future is successful, it returns Ok, otherwise Err.

Most comprehensive way to handle both cases:

let f = File::open("hello.txt");

let mut f = match f {
    Ok(file) => file,
    Err(e) => return Err(e),
};

The above uses the pattern matching syntax which is also great.

This is quite verbose so there are 2 common ways to shorten it:

  1. Using .unwrap()

Example: let my_value = async_function().await.unwrap();

This gets the success value and panics if Err

Use this only when you’re confident that it won’t error or in test environment.

  1. Using the ? syntax

This passes the error up. So your function needs to be able to return an error too (either a Result or an Option)

See this for example and its equivalent

Ownership & References

Heard of the borrow checker? Nothing much for me to say here. It’s the hardest thing in this list since it’s unique to rust. And if you’ve never handled references before, this topic might be a bit steep.

Thankfully the rust book saves the day once again

Basically: Read part 4.1, 4.2 and 4.3

And that’s it!

This list is actually shorter than I expected. I hope it’s useful for your journey.

See a mistake or have any suggestions? Let me know!

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

阅读余下内容
 

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注


京ICP备12002735号