中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

針對JavaScript開發人員的Rust簡介是怎樣的

發布時間:2021-09-30 10:49:44 來源:億速云 閱讀:143 作者:柒染 欄目:編程語言

這期內容當中小編將會給大家帶來有關針對JavaScript開發人員的Rust簡介是怎樣的,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

Rust是2010年起源于Mozilla Research的一種編程語言。如今,所有大公司都在使用它。

亞馬遜和微軟都認可它是其系統中C / C  ++的最佳替代品,但是Rust并不止于此。像Figma和Discord這樣的公司現在也通過在客戶端應用中使用Rust來引領潮流。

針對JavaScript開發人員的Rust簡介是怎樣的

我將從比較Rust和JavaScript開始,然后引導你完成Rust在瀏覽器中運行的步驟。最后,我將介紹一個使用Rust和JavaScript的COVID  simulator web應用程序的快速性能評估。

簡而言之

Rust在概念上與JavaScript非常不同。但也有相似之處需要指出,讓我們來看看問題的兩面。

相似之處

這兩種語言都有一個現代化的包管理系統。JavaScript有npm,Rust有Cargo。Rust有 Cargo.toml 來代替  package.json 進行依賴管理。要創建一個新的項目,使用 cargo init,要運行它,使用 cargo run。不太陌生吧?

Rust中有許多很酷的功能,你已經從JavaScript中知道了,只是語法略有不同。利用這個常見的JavaScript模式,對數組中的每個元素都應用一個閉包:

let staff = [    {name: "George", money: 0},    {name: "Lea", money: 500000}, ]; let salary = 1000; staff.forEach( (employee) => { employee.money += salary; } );

在Rust中,我們可以這樣寫:

let salary = 1000; staff.iter_mut().for_each(      |employee| { employee.money += salary; } );

誠然,習慣這種語法需要時間,用管子( | )代替括號。但在克服了最初的尷尬之后,我發現它比另一組括號讀起來更清晰。

再舉一個例子,這是JavaScript中的對象解構:

let point = { x: 5, y: 10 }; let {x,y} = point;

同樣在Rust中:

let point = Point { x: 5, y: 10 }; let Point { x, y } = point;

主要的區別是,在Rust中我們必須指定類型(Point),更普遍的是,Rust需要在編譯時知道所有類型。但與大多數其他編譯語言不同的是,編譯器盡可能自己推斷類型。

為了進一步解釋這個問題,下面是在C++和許多其他語言中有效的代碼。每個變量都需要明確的類型聲明。

int a = 5; float b = 0.5; float c = 1.5 * a;

在JavaScript以及Rust中,這段代碼是有效的:

let a = 5; let b = 0.5; let c = 1.5 * a;

共享功能不勝枚舉:

  • Rust具有 async + await 語法。

  • 數組可以像讓 let array = [1,2,3] 一樣簡單地創建。

  • 代碼按模塊組織,有明確的導入和導出。

  • 字符串是用Unicode編碼的,處理特殊字符沒有問題。

我可以繼續列舉下去,但我想我的觀點現在已經很清楚了。Rust有一系列豐富的功能,這些功能在現代JavaScript中也有使用。

不同點

Rust是一種編譯語言,這意味著沒有運行時可以執行Rust代碼。一個應用程序只能在編譯器(rustc)完成它的魔法之后運行。這種方法的好處通常是更好的性能。

幸運的是,Cargo為我們解決了調用編譯器的問題。而有了webpack,我們還可以將 Cargo 隱藏在 npm run build  后面。有了這個指南,只要為項目設置好Rust,就可以保留Web開發者的正常工作流程。

Rust  是一種強類型語言,這意味著在編譯時所有類型必須匹配。例如,你不能調用一個參數類型錯誤或參數數量錯誤的函數。編譯器會在你運行時遇到這個錯誤之前為你捕捉到它。顯而易見的比較是TypeScript,如果你喜歡TypeScript,那么你很可能會喜歡Rust。

但別擔心:如果你不喜歡TypeScript,Rust可能還是適合你。Rust  是近幾年從頭開始構建的,它考慮到了過去幾十年來人類在編程語言設計方面所學到的一切。其結果是一種令人耳目一新的簡潔語言。

Rust中的模式匹配是我最喜歡的一個特征,其他語言有 switch 和 case 來避免像這樣的長鏈:

if ( x == 1) {    // ...  } else if ( x == 2 ) {   // ... } else if ( x == 3 || x == 4 ) {   // ... } // ...

Rust使用了如下更優雅的匹配項:

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 <= 10 */},   _ => { /* Catch all other cases */ } }

我認為這是非常整潔的,我希望JavaScript開發人員也能欣賞這種語法擴展。

不幸的是,我們還得談談Rust的黑暗面。直言不諱地說,使用嚴格的類型系統有時會讓人感覺非常繁瑣。如果你認為C++或Java的類型系統很嚴格,那么請準備好迎接Rust的艱難之旅吧。

就我個人而言,我很喜歡Rust這部分。我依賴于嚴格的類型系統,因此可以關閉大腦的一部分&mdash;&mdash;每當我發現自己在編寫JavaScript時,大腦的一部分就會劇烈地興奮起來。但是我知道對于初學者來說,總是和編譯器作對是很煩人的。我們將在稍后的Rust教程中看到一些。

Hello Rust

現在,讓我們用Rust在瀏覽器中運行一個 hello world ,我們首先要確保所有必要的工具都已安裝。

工具

使用rustup安裝Cargo + rustc。  Rustup是推薦的安裝Rust的方法,它將安裝最新的穩定版Rust的編譯器(rustc)和包管理器(Cargo)。它將安裝Rust最新穩定版本的編譯器(rustc)和包管理器(Cargo)。它還可以管理beta版和每夜構建版,但對于本例來說,這不是必需的。

  • 在終端機上輸入 cargo --version 來檢查安裝情況,你應該可以看到 cargo 1.48.0 (65cbdd2dc 2020-10-14)  這樣的內容。

  • 還要檢查Rustup:rustup --version 應該產生 rustup 1.23.0(00924c9ba 2020-11-27)。

安裝wasm-pack。 這是為了將編譯器與npm集成。

  • 通過輸入 wasm-pack --version 來檢查安裝,這應該為您提供 wasm-pack 0.9.1 之類的東西。

我們還需要Node和npm。我們有一篇完整的文章[1]解釋了安裝這兩個的最佳方法。

編寫Rust代碼

現在一切都安裝好了,讓我們來創建項目。最終的代碼也可以在這個GitHub倉庫[2]中找到。我們從一個可以編譯成npm包的Rust項目開始,之后會有導入該包的JavaScript代碼。

要創建一個名為 hello-world 的Rust項目,請使用 cargo init --lib  hello-world。這將創建一個新目錄并生成Rust庫所需的所有文件:

├──hello-world     ├── Cargo.toml     ├── src         ├── lib.rs

Rust代碼將放在 lib.rs 中,在此之前我們必須調整 Cargo.toml。它使用 TOML[3]  定義了依賴關系和其他包的信息。如果想在瀏覽器中看到hello world,請在 Cargo.toml 中的某個地方添加以下行數(例如,在文件的最后)。

[lib] crate-type = ["cdylib"]

這告訴編譯器在C兼容模式下創建一個庫。顯然我們在我們的例子中沒有使用C。C-compatible只是意味著不是Rust專用的,這是我們使用JavaScript中的庫所需要的。

我們還需要兩個外部庫,將它們作為單獨的一行添加到依賴關系部分。

[dependencies] wasm-bindgen = "0.2.68" web-sys = {version = "0.3.45", features = ["console"]}

這些都是來自 crates.io[4] 的依賴項,它是 Cargo 使用的默認包倉庫。

wasm-bindgen[5]是必要的,以創建一個我們以后可以從JavaScript中調用的入口點。(你可以在這里找到完整的文檔。)值 ”0.2.68"  指定了版本。

web-sys[6]包含了所有Web  API的Rust綁定,它將使我們能夠訪問瀏覽器控制臺。請注意,我們必須明確地選擇控制臺功能,我們最終的二進制文件將只包含這樣選擇的Web API綁定。

接下來是 lib.rs 內部的實際代碼。自動生成的單元測試可以刪除。只需使用以下代碼替換文件的內容:

use wasm_bindgen::prelude::*; use web_sys::console;  #[wasm_bindgen] pub fn hello_world() {     console::log_1("Hello world"); }

頂部的 use 語句是用于從其他模塊導入項目。這與JavaScript中的 import 類似)。

pub fn hello_world(){...} 聲明一個函數。pub 修飾符是“public”的縮寫,作用類似于JavaScript中的  export。注釋 #[wasm_bindgen] 特定于Rust編譯為[WebAssembly  (Wasm)](https://webassembly.org/ "wasm_bindgen] 特定于Rust編譯為[WebAssembly (Wasm  "wasm_bindgen] 特定于Rust編譯為[WebAssembly  (Wasm)")")。我們在這里需要它來確保編譯器將包裝函數公開給JavaScript。

在功能主體中,“Hello world”被打印到控制臺上。Rust中的 console :: log_1() 是對 console.log()  的調用的包裝。

你是否注意到函數調用中的 _1 后綴?這是因為JavaScript允許使用可變數量的參數,而Rust不允許。為了解決這個問題, wasm_bindgen  為每種參數數量生成一個函數。是的,這很快就會變得丑陋!但這有效。在web-sys文檔[7]中提供了一個可以在Rust控制臺中調用的完整函數列表。

現在我們應該已經一切就緒,試著用下面的命令編譯它。這將下載所有的依賴項并編譯項目,第一次可能會花一些時間。

cd hello-world wasm-pack build

哈!Rust編譯器對我們不滿意。

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

注意:如果您看到其他錯誤(error: linking with cc failed: exit code:  1)并且你使用的是Linux,則說明缺少交叉編譯依賴性。sudo apt install gcc-multilib 應該可以解決此問題。

正如我前面提到的,編譯器很嚴格。當它期望一個 JsValue  的引用作為一個函數的參數時,它不會接受一個靜態字符串。為了滿足編譯器的要求,必須進行顯式轉換。

console::log_1(&"Hello world".into());

方法 [into()](https://doc.rust-lang.org/std/convert/trait.Into.html "into(  "into()")") 將一個值轉換為另一個值。Rust 編譯器很聰明,它可以推遲哪些類型參與轉換,因為函數簽名只留下了一種可能性。在這種情況下,它將轉換為  JsValue,這是一個由JavaScript管理的值的包裝類型。然后,我們還得加上 &,通過引用而不是通過值來傳遞,否則編譯器又會抱怨。

嘗試再次運行 wasm-pack build,如果一切順利,則最后一行應如下所示:

[INFO]: :-) Your wasm pkg is ready to publish at /home/username/intro-to-rust/hello-world/pkg.

如果你能走到這一步,你現在就可以手動編譯Rust了。下一步,我們將把它與npm和webpack集成,后者將自動為我們完成這項工作。

JavaScript整合

在這個例子中,我決定將 package.json 放在 hello-world  目錄內。我們也可以為Rust項目和JavaScript項目使用不同的目錄,這是個口味問題。

以下是我的 package.json 文件。遵循的最簡單方法是將其復制并運行 npm install,或者運行 npm init 并僅復制 dev  依賴項:

{     "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 <inbox@jakobmeier.ch>",     "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"     } }

如你所見,我們使用的是webpack  5。Wasm-pack也可以和舊版本的webpack一起使用,甚至可以不使用捆綁程序。但每個設置的工作方式都有些不同,我建議你在跟隨這個Rust教程時使用完全相同的版本。

另一個重要的依賴項是 wasm-pack-plugin。這是一個Webpack插件,專門用于加載使用wasm-pack構建的Rust軟件包。

繼續,我們還需要創建 webpack.config.js 文件來配置webpack。它應該是這樣的:

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,     }, };

所有的路徑都配置為Rust代碼和JavaScript代碼并排。index.js 將在 src 文件夾中,緊挨著  lib.rs。如果你喜歡不同的設置,可以隨時調整這些。

你還會注意到,我們使用webpack experiments[8],這是webpack 5引入的新選項。請確保將 syncWebAssembly  設置為true。

最后,我們必須創建JavaScript入口點 src/index.js:

import("../pkg").catch(e => console.error("Failed loading Wasm module:", e)).then(     rust =>         rust.hello_world() );

我們必須異步加載Rust模塊。調用 rust.hello_world() 會調用一個生成的封裝函數,而這個函數又會調用 lib.rs 中定義的Rust函數  hello_world。

現在,運行 npm run serve 應該可以編譯所有內容并啟動開發服務器。我們沒有定義HTML文件,因此頁面上沒有任何顯示。你可能還必須手動轉到  http://localhost:8080/index,因為http://localhost:8080只是列出文件而不執行任何代碼。

打開空白頁后,打開開發人員控制臺。Hello World應該有一個日志條目。

好吧,對于一個簡單的hello world來說,這是相當多的工作。但現在一切都到位了,我們可以輕松地擴展Rust代碼,而不用擔心這些。保存對 lib.rs  的修改后,你應該會自動看到重新編譯和瀏覽器中的實時更新,就像JavaScript一樣。

何時使用Rust

Rust不是JavaScript的一般替代品。它只能通過Wasm在瀏覽器中運行,這在很大程度上限制了它的作用。即使你可以用Rust替換幾乎所有的JavaScript代碼,如果你真的想的話,那是一個壞主意,而且不是Wasm的目的。例如,Rust并不適合與你網站的UI進行交互。

我認為Rust +  Wasm是一個額外的選項,可以用來更有效地運行CPU重的工作負載。以較大的下載量為代價,Wasm避免了JavaScript代碼面臨的解析和編譯開銷。這一點,再加上編譯器的強力優化,可能會帶來更好的性能。這通常是公司為特定項目選擇Rust的原因。選擇Rust的另一個原因可能是語言偏好,但這是一個完全不同的討論,我不會在這里討論。

上述就是小編為大家分享的針對JavaScript開發人員的Rust簡介是怎樣的了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

双峰县| 炎陵县| 本溪市| 洪洞县| 沁阳市| 定陶县| 黑山县| 吴忠市| 资溪县| 宁武县| 泸溪县| 东光县| 保康县| 岫岩| 准格尔旗| 张家界市| 伽师县| 弋阳县| 双柏县| 内丘县| 马鞍山市| 剑河县| 六盘水市| 昂仁县| 太白县| 陆丰市| 茂名市| 大田县| 枞阳县| 库伦旗| 潞城市| 安顺市| 福州市| 沙湾县| 湘潭市| 闸北区| 措美县| 集安市| 常德市| 杂多县| 黄山市|