前端开发者入门Rust:编写第一个有意义的程序
Rust 是一种系统编程语言,以其安全性、并发性和性能而闻名。对于前端开发者来说,学习 Rust 不仅可以拓宽技术视野,还能增强对底层原理的理解。本篇文章将引导前端开发者如何开始使用 Rust 编写第一个有意义的程序。
1. 环境搭建
为什么前端开发者要学习 Rust?
- 性能:Rust 提供了与 C 和 C++ 相当的性能,这对于需要高性能计算的前端应用(如复杂的图形处理)非常有用。
- 安全性:Rust 的所有权和借用系统保证了内存安全,减少内存泄漏和悬挂指针等问题。
- 并发性:Rust 的并发编程模型简单且易于理解,有助于处理高并发场景。
- 生态系统:Rust 拥有一个活跃的社区和丰富的库生态系统,可以快速构建各种应用。
环境搭建
在开始之前,你需要安装 Rust。通过 Rust 的包管理器 cargo
(Rust 的构建工具和包管理器)来安装 Rust 是最简单的方法。
- 访问 Rust 官网 并根据你的操作系统下载安装程序。
- 运行安装程序并按照提示完成安装。新建一个文件夹然后用 vscode 打开,在终端执行下面的命令,然后耐心等待就可以了。
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
- 打开命令提示符 (CMD) ,运行
cargo --version
和rustc --version
来验证安装是否成功。这里强调,再强调,使用的是 CMD 而不是刚才下载的 shell 环境。
编写第一个 Rust 程序
下面将编写一个简单的命令行程序,它接收用户输入并输出一条欢迎信息。
- 创建新项目:在 CMD 中运行
cargo new hello_rust
命令来创建一个新的 Rust 项目。
use std::io;
fn main() {
println!("Hello, please input your name:");
let mut name = String::new();
// 从标准输入读取
io::stdin().read_line(&mut name)
.expect("Failed to read line");
// 去除换行符
let name = name.trim();
println!("Hello, {}! Welcome to the world of Rust.", name);
}
- 运行程序:在
hello_rust
目录下,(CMD 环境下)运行cargo run
来构建并运行程序。程序会等待你输入名字,然后输出欢迎信息。
理解 Rust 代码
use std::io;
:这行代码导入了 Rust 标准库中的io
(输入输出)模块。fn main()
:这是程序的入口点。println!
:这是一个宏,用于打印格式化的字符串到控制台。let mut name = String::new();
:这行代码创建了一个可变的String
类型的变量name
。io::stdin().read_line(&mut name)
:从标准输入读取一行文本到name
变量。expect("Failed to read line")
:如果读取失败,程序将 panic 并显示错误信息。let name = name.trim();
:移除字符串两端的空白字符。
学习途径
前端开发者可以通过以下方式深入学习 Rust:
- 阅读官方文档:Rust 官方文档是学习 Rust 的宝贵资源。
- 参与社区:加入 Rust 社区,如论坛、用户组或在线社区。
- 构建项目:通过构建小项目来实践 Rust,逐步提升编程技能。
- 学习所有权和借用:理解 Rust 的核心特性,如所有权系统和借用规则。
总结
Rust 是一种强大的系统编程语言,它为前端开发者打开了深入计算机科学原理的大门。通过本小节,你已经能够创建并运行一个简单的 Rust 程序。
2. Rust WebAssembly React
结合 Rust 和 React 通常涉及在前端 React 应用中使用 Rust 编译的 WebAssembly(Wasm)模块,以利用 Rust 在性能和安全性方面的优势。以下是将 Rust 与 React 结合的步骤:
步骤 1:设置 Rust 环境
首先,确保你已经安装了 Rust 和 Cargo(Rust 的包管理器)。你可以通过 Rust 官方网站获取安装指南。
步骤 2:创建 Rust WebAssembly 项目
使用 wasm-pack
创建一个新的 Rust Wasm 项目。wasm-pack
是一个工具,用于构建和打包 Rust Wasm 项目。
- 在 CMD 终端中,安装
wasm-pack
:
cargo install wasm-pack
- 在 CMD 终端中,使用
wasm-pack
创建新项目:
wasm-pack new rust-wasm
- 进入项目目录:
cd rust-wasm
- 在 CMD 终端中,构建项目:
wasm-pack build --target web
这将生成一个 pkg
目录,包含编译后的 Wasm 二进制文件和 JavaScript 包装器。
步骤 3:在 React 应用中使用 Rust Wasm 模块
(首先使用 create-react-app 快速创建一个前端项目)
- 将 rust-wasm 整个文件夹复制到前端项目的根目录下,在 React 应用中安装生成的 Wasm 包:
yanr add ./rust-wasm/pkg
这里一定要注意是 相对路径!!!
安装成功之后就可以在 node_modules
中看到了:
注意!从命令中不难看出来,实际上我们在前端中用到的只是 ./rust-wasm/pkg 中的内容,因此没有必要将整个项目都复制过来,只需复制 ./rust-wasm/pkg 目录即可。
- 在 React 组件中导入和使用 Rust Wasm 模块:
import React from 'react';
const App = () => {
const greet = async () => {
const rustApp = import('rust-wasm');
const r = await (await rustApp).default();
r.greet();
};
return (
<div>
<h1>Rust and React Integration</h1>
<button onClick={greet}>Run Computation</button>
</div>
);
};
export default App;
点击按钮之后,alert 出现,则上面所有的步骤成功。
步骤 4:编写 Rust 代码并导出函数
在 Rust 项目中,编写所需的功能并使用 #[wasm_bindgen]
宏导出函数,使其可以在 JavaScript 中调用。
在我们的 rust-wasm 项目中,打开 rust-wasm\src\lib.rs
文件,其内容为:
mod utils;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
}
#[wasm_bindgen]
pub fn greet() {
alert("Hello, rust-wasm!");
}
往其中增加一个自定义函数,名为:climb_stairs
#[wasm_bindgen]
pub fn someRustFunction() -> String {
// Rust 逻辑
return "Hello from Rust!".to_string()
}
#[wasm_bindgen]
pub fn climb_stairs(n: i32) -> i32 {
if n <= 2 {
return n
}
return climb_stairs(n - 1) + climb_stairs(n - 2);
}
步骤 5:构建并测试
每次修改 Rust 代码后,都需要重新构建 Rust Wasm 模块,并重新安装到 React 项目中。
- 在 Rust 项目目录中运行:
wasm-pack build --target web
- 将打包好的项目重新复制到前端项目,并按照刚才的步骤进行安装。
yanr add ./rust-wasm/pkg
- 回到 React 应用,运行开发服务器:
yarn start
- 将加载结果打印出来,不难看到这个时候已经挂载上我们新增的函数了
- 尝试执行的效果如下:
注意事项
- 确保 Rust 项目中的
Cargo.toml
文件包含wasm-bindgen
依赖。 - 测试 Rust 和 React 之间的接口,确保类型正确转换。
3. 使用 Rust 编写第一个有意义的 Web Assembly 并在 React 中使用
要实现这个功能,我们将分为两个主要步骤进行:
步骤 1:使用 Rust 编写 WebAssembly 模块
首先,我们将创建一个 Rust 项目,该模块将加载图像、将其转换为灰度,然后返回图像数据的Base64编码。
- 设置 Rust Wasm 项目:
使用 wasm-pack
创建一个新的 Rust Wasm 项目:
wasm-pack new rust-image-processor
进入项目目录:
cd rust-image-processor
- 添加依赖:
在 Cargo.toml
文件中,添加必要的依赖,如 web-sys
、wasm-bindgen
和 image
。
[dependencies]
wasm-bindgen = "0.2"
web-sys = "0.3"
wasm-bindgen-futures = "0.4"
image = "0.23"
console_log = "0.2"
log = "0.4"
- 编写 Rust 代码:
在 src/lib.rs
文件中,编写以下代码:
extern crate image;
extern crate console_log;
extern crate log;
use log::*;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn grayscale_image(image_data: Vec<u8>) -> Vec<u8> {
if image_data.is_empty() {
info!("Image data is empty.");
}
let img = image::load_from_memory(&image_data).unwrap();
let gray_img = img.grayscale();
let mut buf: Vec<u8> = vec![];
gray_img.write_to(&mut buf, image::ImageOutputFormat::Png).unwrap();
buf
}
#[wasm_bindgen(start)]
pub fn main() {
console_log::init_with_level(log::Level::Info).unwrap();
}
- 构建 Rust Wasm 模块:
wasm-pack build --target web
步骤 2:在 React 应用中使用 Rust Wasm 模块
- 安装生成的 Wasm 包:
yarn add ./rust-image-processor/pkg
- 在 React 组件中使用 Rust Wasm 模块:
import React, {useState, useEffect} from 'react';
const _imageUrl = 'https://images.pexels.com/photos/12196392/pexels-photo-12196392.jpeg?auto=compress&cs=tinysrgb&w=600&lazy=load';
const App = ({imageUrl=_imageUrl}) => {
const [grayImageUrl, setGrayImageUrl] = useState(imageUrl);
useEffect(() => {
const processor = async () => {
const rustApp = import('rust-image-processor');
const r = await (await rustApp).default();
const response = await fetch(imageUrl);
const arrayBuffer = await response.arrayBuffer();
const _ = new Uint8Array(arrayBuffer);
const grayImage = r.grayscale_image(_);
const blob = new Blob([grayImage], { type: 'image/png' });
setGrayImageUrl(URL.createObjectURL(blob));
};
processor();
}, [imageUrl]);
return <img src={grayImageUrl} alt="Grayscale Image" />;
};
export default App;
至此,我们创建了一个简单的React组件,允许用户输入图像URL,然后调用Rust编写的Wasm模块来处理图像,并将处理后的图像URL显示出来。
转载自:https://juejin.cn/post/7362370608346906659