rust wasm入门

在这里插入图片描述

📕作者简介: 过去日记,致力于Java、GoLang,Rust等多种编程语言,热爱技术,喜欢游戏的博主。
📘相关专栏Rust初阶教程、go语言基础系列、spring教程等,大家有兴趣的可以看一看
📙Java并发编程系列,设计模式系列、go web开发框架 系列正在发展中,喜欢Java,GoLang,Rust,的朋友们可以关注一下哦!


@[TOC] # demo ## 编译 Rust 为 WebAssembly

在本教程中,我们将使用 Rust 的 npm 包构建工具 wasm-pack 来构建一个 npm 包。这个包只包含 WebAssembly 和 JavaScript 代码,以便包的用户无需安装 Rust 就能使用。他们甚至不需要知道这里包含 WebAssembly!

安装 Rust 环境

安装 Rust

前往 Install Rust 页面并跟随指示安装 Rust。这里会安装一个名为“rustup”的工具,这个工具能让你管理多个不同版本的 Rust。默认情况下,它会安装用于惯常 Rust 开发的 stable 版本 Rust Release。Rustup 会安装 Rust 的编译器 rustc、Rust 的包管理工具 cargo、Rust 的标准库 rust-std 以及一些有用的文档 rust-docs。

wasm-pack

要构建我们的包,我们需要一个额外工具 wasm-pack。它会帮助我们把我们的代码编译成 WebAssembly 并制造出正确的 npm 包。使用下面的命令可以下载并安装它:

cargo install wasm-pack

安装 Node.js 并获取 npm 账户

在这个例子中我们将会构建一个 npm 包,因此你需要确保安装 Node.js 和 npm 已经安装。另外,我们将会把包发布到 npm 上,因此你还需要一个 npm 账号。它们是免费的.
在 npm signup page 注册 npm 账户,并填写表格。

接下来,在命令行中运行 npm adduser:

> npm adduser
Username: yournpmusername
Password:
Email: (this IS public) you@example.com

Logged in as yournpmusername on https://registry.npmjs.org/.
如果并未正常运行,请联系 npm 解决。

构建我们的 WebAssembly npm 包

万事俱备,来创建一个新的 Rust 包吧。打开你用来存放你私人项目的目录,做这些事:

$ cargo new --lib hello-wasmCreated library `hello-wasm` project

这里会在名为 hello-wasm 的子目录里创建一个新的库,里面有下一步之前你所需要的一切:

+-- Cargo.toml
+-- src+-- lib.rs

首先,我们有一个 Cargo.toml 文件,这是我们配置构建的方式。

接下来,Cargo 在 src/lib.rs 生成了一些 Rust 代码:

#[cfg(test)]
mod tests {#[test]fn it_works() {assert_eq!(2 + 2, 4);}
}

我们完全不需要使用这些测试代码,所以继续吧,我们删掉它。

让我们在 src/lib.rs 写一些代码替换掉原来的:

extern crate wasm_bindgen;use wasm_bindgen::prelude::*;#[wasm_bindgen]
extern {pub fn alert(s: &str);
}#[wasm_bindgen]
pub fn greet(name: &str) {alert(&format!("Hello, {}!", name));
}

使用 wasm-bindgen 在 Rust 与 JavaScript 之间通信
第一部分看起来像这样:

extern crate wasm_bindgen;

use wasm_bindgen::prelude:😗;
第一行就像在说“哇 Rust,我们在用一个叫做 wasm_bindgen 的库”。在 Rust 当中,库被称为“crates”,因为我们使用的是一个外部库,所以有 “extern”。

第三行包括了一个将库中的代码引入到你的代码中的使用命令。
wasm-pack 使用另一个工具 wasm-bindgen 来提供 JavaScript 和 Rust 类型之间的桥梁。它允许 JavaScript 使用字符串调用 Rust API,或调用 Rust 函数来捕获 JavaScript 异常。

在 Rust 中调用来自 JavaScript 的外部函数
接下来的部分看起来像这样:

#[wasm_bindgen]
extern {pub fn alert(s: &str);
}

在 #[] 中的内容叫做 “属性”,并以某种方式改变下面的语句。在这种情况下,下面的语句是一个 extern,它将告诉 Rust that 我们想调用一些外部定义的函数。这个属性告诉我们 “wasm-bindgen 知道如何找到这些函数”。

第三行是用 Rust 写的函数签名。它告诉我们 “alert 函数接受一个叫做 s 的字符串作为参数。”

当你想调用新的 JavaScript 函数时,你可以在这里写他们,wasm-bindgen 将负责为你设置一切。

编写能够在 JavaScript 中调用的 Rust 函数
最后一部分是这样的:

#[wasm_bindgen]
pub fn greet(name: &str) {alert(&format!("Hello, {}!", name));
}

我们又看到了 #[wasm_bindgen] 属性。在这里,它并非定义一个 extern 块,而是 fn,这代表我们希望能够在 JavaScript 中使用这个 Rust 函数。这和 extern 正相反:我们并非引入函数,而是要把函数给外部世界使用。

这个函数的名字是 greet,它需要一个参数,一个字符串(写作 &str)。它调用了我们前面在 extern 块中引入的 alert 函数。它传递了一个让我们串联字符串的 format! 宏的调用。

format! 在这里有两个参数,一个格式化字符串和一个要填入的变量。格式化字符串是 “Hello, {}!” 部分。它可以包含一个或多个 {},变量将会被填入其中。传递的变量是 name,也就是这个函数的参数。所以当我们调用 greet(“Steve”)时我们就能看到 “Hello, Steve!”。

上述字符串被传递到了 alert(),所以当我们调用这个函数时,我们应该能看到一个消息框弹出,其中的内容为“Hello, Steve!”。

把我们的代码编译到 WebAssembly

为了能够正确的编译我们的代码,首先我们需要配置 Cargo.toml。打开这个文件,将内容改为如下所示:

Copy to Clipboard
[package]
name = "hello-wasm"
version = "0.1.0"
authors = ["Your Name <you@example.com>"]
description = "A sample project with wasm-pack"
license = "MIT/Apache-2.0"
repository = "https://github.com/yourgithubusername/hello-wasm"[lib]
crate-type = ["cdylib"][dependencies]
wasm-bindgen = "0.2"

你需要改为自己的仓库,同时 Cargo 需要通过 git 来完善 authors 部分。

最重要的是添加底下的部分。第一个部分 — [lib] — 告诉 Rust 为我们的包建立一个 cdylib 版本;在本教程中我们不会讲解它的含义。
第二个部分是 [dependencies] 部分。在这里我们告诉 Cargo 我们需要依赖哪个版本的 wasm-bindgen ;在这个例子中,它是 0.2.z 版本的 (不是 0.3.0 或者其他版本)。

构建包

现在我们已经完成了所有配置项,开始构建吧!在命令行输入以下命令:

wasm-pack build --scope mynpmusername
这个命令将做一系列事情 (这会花一些时间,特别是当你第一次运行 wasm-pack)。

把我们的包发布到 npm

把我们的新包发布到 npm registry:

cd pkg
npm publish --access=public

我们现在有了一个 npm 包,使用 Rust 编写,但已经被编译为 WebAssembly 了。现在这个包已经可以被 JavaScript 使用了,而且使用它完全不需要用户安装 Rust;包中的代码是 WebAssembly 代码,而不是 Rust 源码!

在网站上使用我们的包

让我们建立一个使用我们包的网站!人们通过各种打包工具使用 npm 包,在本教程中,我们将使用 webpack。它比其他某些打包工具稍微复杂一点,但展示了更实际的用法。

让我们离开pkg目录,并创建一个新目录site,尝试以下操作:

cd ../..
mkdir site
cd site

创建一个新文件 package.json,然后输入如下代码:

{"scripts": {"serve": "webpack-dev-server"},"dependencies": {"@mynpmusername/hello-wasm": "^0.1.0"},"devDependencies": {"webpack": "^4.25.1","webpack-cli": "^3.1.2","webpack-dev-server": "^3.1.10"}
}

请注意,你需要在依赖项部分的 @ 之后填写自己的用户名。

接下来,我们需要配置 Webpack。创建 webpack.config.js 并输入:

const path = require("path");
module.exports = {entry: "./index.js",output: {path: path.resolve(__dirname, "dist"),filename: "index.js",},mode: "development",
};

现在我们需要一个 HTML 文件。创建一个index.html并写入如下内容:

<!doctype html>
<html><head><meta charset="utf-8" /><title>hello-wasm example</title></head><body><script src="./index.js"></script></body>
</html>

最后,从 HTML 文件中引用index.js:

const js = import("./node_modules/@yournpmusername/hello-wasm/hello_wasm.js");
js.then((js) => {js.greet("WebAssembly");
});

这将从node_modules文件夹导入我们的模块。这不是最佳做法,但这里只做一个演示,因此暂时就这样用。加载后,它将从该模块调用greet函数,并传入字符串“WebAssembly”参数。注意这里看上去没有什么特别的,但是我们正在调用 Rust 代码!就 JavaScript 代码所知,这只是一个普通模块。

我们已经完成了所有的文件!让我们试一下:

npm install
npm run serve

这将启动一个 Web 服务器。访问 http://localhost:8080,你应该会在屏幕上看到一个内容为 Hello, WebAssembly! 的警告框。我们已经成功地从 JavaScript 调用了 Rust,并从 Rust 调用了 JavaScript。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/305787.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

连续6年!九州未来获评2024中国边缘计算企业20强

4月9日&#xff0c;由国内中立边缘计算领域研究平台——边缘计算社区策划发起的“2024中国边缘计算企业20强”榜单正式揭晓&#xff0c;九州未来凭借在边缘计算领域的深厚积累以及创新实践&#xff0c;从众多参评企业中脱颖而出&#xff0c;连续6年入选中国边缘计算企业20强&am…

vue3第十八节(diff算法)

引言&#xff1a; 上一节说了key的用途&#xff0c;而这个key属性&#xff0c;在vue的vnode 中至关重要&#xff0c;直接影响了虚拟DOM的更新机制&#xff1b; 什么场景中会用到diff算法 如&#xff1a;修改响应式属性需要重新渲染页面&#xff0c;会重新执行render渲染函数返…

智慧之旅不止步!凌恩生物3月客户文章累计IF>314.8!

2024年3月&#xff0c;凌恩生物助力客户发表文章63篇&#xff0c;累计影响因子314.8分&#xff0c;其中包括Science of the Total Environment、Journal of Hazardous Materials、Carbohydrate Polymers、Genome Biology、Chemical Engineering Journal、Bioresource Technolog…

从 SQLite 3.5.9 迁移到 3.6.0(二十一)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;从 SQLite 3.4.2 迁移到 3.5.0&#xff08;二十&#xff09; 下一篇&#xff1a;SQLite—系列文章目录 ​SQLite 版本 3.6.0 &#xff08;2008-07-16&#xff09; 包含许多更改。按照惯例 SQLite项目&#xff…

关于centos8自带的apache2.4开启https后,XP系统的IE8无法显示网页的问题

经检验&#xff0c;是因为系统的apache和openssl版本太高导致的。 禁用系统默认的apache2.4&#xff0c;自己重新源码编译安装一套openssl-1.0.1fapache2.2.23php7.1.2即可。跟update-crypto-policies没有关系&#xff0c;可保持默认的DEFAULT状态。 关于centos8自带的apache2…

故障诊断 | 基于LSTM的滚动轴承故障诊断

效果 概述 基于LSTM(长短期记忆网络)的滚动轴承故障诊断是一种利用深度学习技术来预测滚动轴承是否存在故障的方法。下面是一个基本的滚动轴承故障诊断的流程: 数据收集:首先,需要收集与滚动轴承相关的振动信号数据。这些数据可以通过传感器或振动监测系统获取。收集的数…

Redis入门到通关之Redis介绍

文章目录 1.Redis简单介绍1.1 非关系型数据库介绍 2.本文介绍如下内容3.初始Redis3.1.认识NoSQL3.1.3.查询方式3.1.4.事务3.1.5.总结 3.2.认识Redis3.3 安装Redis 1.Redis简单介绍 Redis是一种键值型的 NoSql 数据库&#xff0c;这里有两个关键字&#xff1a; 键值型NoSql 其…

不通过command,通过idea配置启动项

有同学问&#xff0c;不通过npm run dev这几个字母输入在控制台如何运行呢&#xff1f; 哦&#xff0c;还真有&#xff0c;不过原理是一样的&#xff0c;下面来看看叭 点击左上角的编辑配置Edit Configurations 进来之后点击左上角的加号 点击npm&#xff0c;package.json选择…

Python八股文:基础知识Part1

1. 不用中间变量交换 a 和 b 这是python非常方便的一个功能可以这样直接交换两个值 2. 可变数据类型字典在for 循环中进行修改 这道题在这里就是让我们去回答输出的内容&#xff0c;这里看似我们是在for循环中每一次加入了都在list中加入了一个字典&#xff0c;然后字典的键值…

Python机器学习学习线路

随着人工智能技术的飞速发展&#xff0c;机器学习已经成为计算机科学领域的热门话题。Python&#xff0c;作为一门功能强大且易于上手的编程语言&#xff0c;成为学习机器学习的理想选择。本文将为您介绍一条Python机器学习的学习线路&#xff0c;帮助您逐步掌握机器学习的基础…

嵌入式学习53-ARM2

知识零碎&#xff1a; 跳转指令b&#xff1a; b 指令类似c语言的goto语句&#xff0c;能够实现无条件跳转。跳…

铸铁试验平台和铸铁实验平台的主要区别在哪——北重制造厂家

铸铁试验平台和铸铁实验平台的主要区别在于其使用目的、实验内容和功能。 首先&#xff0c;铸铁试验平台主要用于铸铁工艺试验和工艺参数优化。通过模拟铸铁工艺过程&#xff0c;对不同工艺参数进行试验&#xff0c;从而得到最佳的铸铁工艺参数。铸铁试验平台一般具有温度控制、…

【开源语音项目OpenVoice](一)——实操演示

目录 一、前菜 1、Python选择 2、pip源切换 3、ffmpeg配置问题 4、VSCode添加Jupyter扩展 二、配置虚拟环境 1、下载源码 方法一 直接下载源码压缩包 方法二 使用git 1&#xff09;git加入鼠标右键 2&#xff09;git clone源码 2、VSCode出场 1&#xff09;创建pyth…

【复现】浙大恩特客户资源管理系统 SQL注入漏洞_71

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 浙大恩特客户资源管理系统是一款针对企业客户资源管理的软件产品。该系统旨在帮助企业高效地管理和利用客户资源&#xff0c;提升…

【C++】手搓 list 容器

送给大家一句话&#xff1a; 若结局非你所愿&#xff0c;就在尘埃落定前奋力一搏。—— 《夏目友人帐》 手搓 list 容器 1 前言1.1 底层结构1.2 使用场景1.3 功能简介 2 框架搭建2.1 节点类2.2 list 类2.3 迭代器类 3 功能实现3.1 begin() 与 end()3.2 插入操作3.3 删除操作3…

【MCU开发规范】:MCU的性能测试

MCU的性能测试 前序性能评判方法MIPSCoreMark EEMBC其他参考 前序 我们平时做MCU开发时&#xff0c;前期硬件选型&#xff08;选那颗MCU&#xff09;基本由硬件工程师和架构决定&#xff0c;到软件开发时只是被动的开发一些具体功能&#xff0c;因此很少参与MCU的选型。 大部分…

编程规范(保姆级教程)

文章目录 为什么需要编程规范&#xff1f;&#x1f4a1;代码检测工具 ESLint&#x1f4a1;代码格式化 Prettier&#x1f4a1;ESLint 与 Prettier 配合解决代码格式问题eslint支持ts约定式提交规范Commitizen助你规范化提交代码什么是 Git Hooks使用 husky commitlint 检查提交…

ubuntu如何截图? ubuntu中截屏的三种方法

文章目录 1.ubuntu主要用途2.ubuntu如何截图&#xff1f;2.1 方法一&#xff1a;键盘按键快捷键截屏 2.2 方法二&#xff1a;系统自带软件2.3 方法三&#xff1a;第三方软件 Reference 1.ubuntu主要用途 1、桌面操作系统&#xff1a;Ubuntu可用作个人电脑或笔记本电脑的操作系…

3.网络编程-TCP

目录 TCP 建立连接的过程是怎样的 TCP为什么是三次握手 TCP 断开连接的过程是怎样的 TCP挥手为什么需要四次 为什么TIME_WAIT等待的时间是2MSL TCP详解之滑动窗口 TCP 半连接队列和全连接队列是什么 TCP粘包&#xff0c;拆包是怎么发生的&#xff0c;如何解决 TCP是如何…

Mapbox教程:一个简单Demo

近期工作中准备把Mapbox用起来&#xff0c;准备发几个教程&#xff0c;把Mapbox再熟悉熟悉。工作中也用过不少的Web GIS组件&#xff0c;在这里说一下我对这些WebGIS组件的印象。 Leaflet 代码简洁&#xff0c;插件丰富&#xff0c;相比于其大小&#xff0c;功能也挺强大&#…