In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
In this issue, the editor will bring you a brief introduction to Rust for JavaScript developers. The article is rich in content and analyzed and described from a professional point of view. I hope you can get something after reading this article.
Rust is a programming language that originated from Mozilla Research in 2010. Today, all the big companies are using it.
Both Amazon and Microsoft agree that it is the best alternative to C / C + in their systems, but Rust is more than that. Companies like Figma and Discord are also leading the trend by using Rust in client applications.
I'll start by comparing Rust and JavaScript, and then guide you through the steps for Rust to run in the browser. Finally, I'll introduce a quick performance evaluation of a COVID simulator web application that uses Rust and JavaScript.
In short
Rust is conceptually very different from JavaScript. But there are similarities to point out. Let's look at both sides of the problem.
similarity
Both languages have a modern package management system. JavaScript has npm,Rust and Cargo. Rust has Cargo.toml instead of package.json for dependency management. To create a new project, use cargo init. To run it, use cargo run. It's not strange, is it?
There are a lot of cool features in Rust, which you already know from JavaScript, but the syntax is slightly different. Using this common JavaScript pattern, a closure is applied to each element in the array:
Let staff = [{name: "George", money: 0}, {name: "Lea", money: 500000},]; let salary = 1000; staff.forEach ((employee) = > {employee.money + = salary;})
In Rust, we can write:
Let salary = 1000; staff.iter_mut () .for_each (| employee | {employee.money + = salary;})
Admittedly, it takes time to get used to this syntax, using tubes (|) instead of parentheses. But after overcoming the initial embarrassment, I found it read more clearly than another set of parentheses.
To take another example, this is object deconstruction in JavaScript:
Let point = {x: 5, y: 10}; let {x _ 5y} = point
Also in Rust:
Let point = Point {x: 5, y: 10}; let Point {x, y} = point
The main difference is that in Rust we have to specify Point, and more generally, Rust needs to know all types at compile time. But unlike most other compiled languages, compilers infer types themselves as much as possible.
To further explain this, here is the code that works in C++ and many other languages. Each variable requires an explicit type declaration.
Int a = 5; float b = 0.5; float c = 1.5 * a
In JavaScript and Rust, this code is valid:
Let a = 5; let b = 0.5; let c = 1.5 * a
There are numerous sharing features:
Rust has async + await syntax.
Arrays can be created as easily as having let array = [1, 2, 5, 3].
The code is organized by module, with clear import and export.
Strings are encoded in Unicode, so there is no problem with handling special characters.
I can continue to list, but I think my point is very clear now. Rust has a rich set of features that are also used in modern JavaScript.
Differences
Rust is a compiled language, which means that there is no runtime to execute Rust code. An application can only be run after the compiler (rustc) has completed its magic. The benefit of this approach is usually better performance.
Fortunately, Cargo solves the problem of invoking the compiler for us. With webpack, we can also hide Cargo behind npm run build. With this guide, as long as you set up Rust for your project, you can maintain the normal workflow of Web developers.
Rust is a strongly typed language, which means that all types must match at compile time. For example, you cannot call a function with the wrong type or number of parameters. The compiler will catch this error for you before you encounter it at run time. The obvious comparison is TypeScript, if you like TypeScript, then you will probably like Rust.
But don't worry: if you don't like TypeScript,Rust, it might still suit you. Rust was built from scratch in recent years, taking into account everything humans have learned in programming language design over the past few decades. The result is a refreshing and concise language.
Pattern matching in Rust is one of my favorite features, and other languages have switch and case to avoid long chains like this:
If (x = = 1) {/ /...} else if (x = = 2) {/ /...} else if (x = = 3 | | x = = 4) {/ /...} / /.
Rust uses the following more elegant matches:
Match x {1 = > {/ * Do something if x = = 1 * /}, 2 = > {/ * Do something if x = = 2 * /}, 3 | 4 = > {/ * Do something if x = = 3 | x = = 4 * /}, 5.. 10 = > {/ * Do something if x > = 5 & & x {/ * Catch all other cases * /}}
I think this is very neat, and I hope JavaScript developers will appreciate this syntax extension as well.
Unfortunately, we also need to talk about the dark side of Rust. To put it bluntly, using a strict type system can sometimes feel tedious. If you think C++ or Java's typing system is strict, prepare for the tough ride of Rust.
Personally, I like the Rust part very much. I rely on a strict typing system, so I can turn off part of the brain-every time I find myself writing JavaScript, part of the brain gets excited. But I know it's annoying for beginners to always fight against the compiler. We'll see some later in the Rust tutorial.
Hello Rust
Now, let's run a hello world in a browser using Rust, and first make sure that all the necessary tools are installed.
Tools
Use rustup to install Cargo + rustc. Rustup is the recommended way to install Rust, which will install the latest stable version of Rust's compiler (rustc) and package manager (Cargo). It will install the latest stable version of Rust's compiler (rustc) and package manager (Cargo). It can also manage the beta version and the nightly build, but this is not required for this example.
Type cargo-- version on the terminal to check the installation, and you should see something like cargo 1.48.0 (65cbdd2dc 2020-10-14).
Also check that Rustup:rustup-- version should produce rustup 1.23.0 (00924c9ba 2020-11-27).
Install wasm-pack. This is to integrate the compiler with npm.
Check the installation by typing wasm-pack-- version, which should provide you with things like wasm-pack 0.9.1.
We also need Node and npm. We have a complete article [1] that explains the best way to install these two.
Write Rust code
Now that everything is installed, let's create the project. The final code can also be found in this GitHub repository [2]. Let's start with a Rust project that can be compiled into a npm package, followed by JavaScript code that imports the package.
To create a Rust project named hello-world, use cargo init-- lib hello-world. This creates a new directory and generates all the files required by the Rust library:
├── hello-world ├── Cargo.toml ├── src ├── lib.rs
The Rust code will be placed in the lib.rs, and we must adjust the Cargo.toml before that. It uses TOML [3] to define dependencies and other package information. If you want to see hello world in your browser, add the following lines somewhere in Cargo.toml (for example, at the end of the file).
[lib] crate-type = ["cdylib"]
This tells the compiler to create a library in C compatibility mode. Obviously we didn't use C in our example. C-compatible simply means that it is not Rust-specific, which is what we need to use libraries in JavaScript.
We also need two external libraries to add them as separate lines to the dependencies section.
[dependencies] wasm-bindgen = "0.2.68" web-sys = {version = "0.3.45", features = ["console"]}
These are dependencies from crates.io [4], which is the default package repository used by Cargo.
Wasm-bindgen [5] is necessary to create an entry point that we can call from JavaScript later. You can find the complete document here.) The value "0.2.68" specifies the version.
Web-sys [6] contains all the Rust bindings for Web API, which will give us access to the browser console. Note that we must explicitly select the console function, and our final binaries will contain only the Web API bindings of this choice.
Next is the actual code inside lib.rs. Automatically generated unit tests can be deleted. Simply replace the contents of the file with the following code:
Use wasm_bindgen::prelude::*; use web_sys::console; # [wasm_bindgen] pub fn hello_world () {console::log_1 ("Hello world");}
The use statement at the top is used to import projects from other modules. This is similar to import in JavaScript).
Pub fn hello_world () {...} declares a function. The pub modifier is an abbreviation for "public" and acts like export in JavaScript. Note # [wasm_bindgen] is specific to Rust compilation to [WebAssembly (Wasm)] (https://webassembly.org/ "wasm_bindgen] is specific to Rust compilation to [WebAssembly (Wasm" wasm_bindgen] specific to Rust compilation to [WebAssembly (Wasm) "). We need it here to ensure that the compiler exposes the wrapper function to JavaScript.
In the function body, "Hello world" is printed to the console. Console:: log_1 () in Rust is a wrapper for a call to console.log ().
Have you noticed the _ 1 suffix in the function call? This is because JavaScript allows the use of a variable number of parameters, while Rust does not. To solve this problem, wasm_bindgen generates a function for each number of parameters. Yes, it will soon become ugly! But it works. A complete list of functions that can be called in the Rust console is provided in the web-sys document [7].
Now that we have everything in place, try to compile it with the following command. This will download all the dependencies and compile the project, which may take some time the first time.
Cd hello-world wasm-pack build
Ha! the Rust compiler is not satisfied with us.
Error [E0308]: mismatched types-- > src\ lib.rs:6:20 | 6 | console::log_1 ("Hello world"); ^ expected struct `JsValue`, found `str` | = note: expected reference `& JsValue`found reference` & 'static str
Note: if you see other errors (error: linking with cc failed: exit code: 1) and you are using Linux, there is a lack of cross-compilation dependencies. Sudo apt install gcc-multilib should solve this problem.
As I mentioned earlier, the compiler is very strict. When it expects a reference to JsValue as an argument to a function, it does not accept a static string. In order to meet the requirements of the compiler, explicit conversion must be performed.
Console::log_1 (& "Hello world" .into ())
The method [into ()] (https://doc.rust-lang.org/std/convert/trait.Into.html "into (" into () ")) converts one value to another. The Rust compiler is smart enough to postpone which types participate in the conversion because function signatures leave only one possibility. In this case, it will be converted to JsValue, which is a wrapper type for values managed by JavaScript. Then we have to add & passed by reference rather than by value or the compiler will complain again.
Try to run wasm-pack build again, and if all goes well, the last line should look like this:
[INFO]: -) Your wasm pkg is ready to publish at / home/username/intro-to-rust/hello-world/pkg.
If you can make it this far, you can compile Rust manually now. Next, we will integrate it with npm and webpack, which will automatically do this for us.
JavaScript integration
In this example, I decided to put package.json in the hello-world directory. We can also use different directories for Rust projects and JavaScript projects, which is a matter of taste.
The following is my package.json file. The easiest way to follow is to copy and run npm install, or run npm init and copy only the dev dependencies:
{"name": "hello-world", "version": "1.0.0", "description": "Hello world app for Rust in the browser.", "main": "index.js", "scripts": {"build": "webpack", "serve": "webpack serve"}, "author": "Jakob Meier" "license": "(MIT OR Apache-2.0)", "devDependencies": {"@ wasm-tool/wasm-pack-plugin": "~ 1.3.1", "@ webpack-cli/serve": "^ 1.1.0", "css-loader": "^ 5.0.1", "style-loader": "^ 2.0.0" "webpack": "~ 5.8.0", "webpack-cli": "~ 4.2.0", "webpack-dev-server": "~ 3.11.0"}}
As you can see, we are using webpack 5. Wasm-pack can also be used with older versions of webpack, even without using bundles. But each setting works a little differently, and I recommend that you use exactly the same version when following this Rust tutorial.
Another important dependency is wasm-pack-plugin. This is a Webpack plug-in designed to load Rust packages built using wasm-pack.
To continue, we also need to create a webpack.config.js file to configure webpack. It should look like this:
Const path = require ('path'); const webpack = require (' webpack'); const WasmPackPlugin = require ("@ wasm-tool/wasm-pack-plugin") Module.exports = {entry:'. / src/index.js', output: {path: path.resolve (_ _ dirname, 'dist'), filename:' index.js',}, plugins: [new WasmPackPlugin ({crateDirectory: path.resolve (_ _ dirname, ".)}),], devServer: {contentBase:". / src " Hot: true,}, module: {rules: [{test: /\ .css $/ I, use: ["style-loader", "css-loader"],},]}, experiments: {syncWebAssembly: true,},}
All paths are configured with Rust code and JavaScript code side by side. Index.js will be in the src folder, next to lib.rs. If you like different settings, you can adjust them at any time.
You will also notice that we use webpack experiments [8], which is a new option introduced by webpack 5. Make sure that syncWebAssembly is set to true.
Finally, we must create the JavaScript entry point src/index.js:
Import (".. / pkg") .catch (e = > console.error ("Failed loading Wasm module:", e)) .then (rust = > rust.hello_world ())
We must load the Rust module asynchronously. Calling rust.hello_world () invokes a generated wrapper function, which in turn calls the Rust function hello_world defined in lib.rs.
Now, running npm run serve should compile everything and start the development server. We don't have a HTML file defined, so there's nothing to show on the page. You may also have to manually go to http://localhost:8080/index, because http://localhost:8080 just lists files and doesn't execute any code.
After opening the blank page, open the developer console. Hello World should have a log entry.
Well, for a simple hello world, this is quite a lot of work. But now that everything is in place, we can easily extend the Rust code without worrying about it. After saving the changes to lib.rs, you should automatically see recompilations and real-time updates in the browser, just like JavaScript.
When to use Rust
Rust is not a general substitute for JavaScript. It can only be run in browsers through Wasm, which largely limits its use. Even if you can replace almost all JavaScript code with Rust, that's a bad idea if you really want to, and it's not the purpose of Wasm. For example, Rust is not suitable for interacting with the UI of your site.
I think Rust + Wasm is an additional option that can be used to run CPU heavy workloads more efficiently. At the expense of a large number of downloads, Wasm avoids the parsing and compilation overhead faced by JavaScript code. This, coupled with the strong optimization of the compiler, may lead to better performance. This is usually why companies choose Rust for specific projects. Another reason for choosing Rust may be language preference, but this is a completely different discussion and I won't discuss it here.
The above is the brief introduction of Rust for JavaScript developers shared by Xiaobian. If you happen to have similar doubts, you might as well refer to the above analysis to understand. If you want to know more about it, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.