掘金 后端 ( ) • 2024-04-28 13:41

Rust 是一种系统编程语言,以其安全性、并发性和性能而闻名。对于前端开发者来说,学习 Rust 不仅可以拓宽技术视野,还能增强对底层原理的理解。本篇文章将引导前端开发者如何开始使用 Rust 编写第一个有意义的程序。

1. 环境搭建

为什么前端开发者要学习 Rust?

  1. 性能:Rust 提供了与 C 和 C++ 相当的性能,这对于需要高性能计算的前端应用(如复杂的图形处理)非常有用。
  2. 安全性:Rust 的所有权和借用系统保证了内存安全,减少内存泄漏和悬挂指针等问题。
  3. 并发性:Rust 的并发编程模型简单且易于理解,有助于处理高并发场景。
  4. 生态系统:Rust 拥有一个活跃的社区和丰富的库生态系统,可以快速构建各种应用。

环境搭建

在开始之前,你需要安装 Rust。通过 Rust 的包管理器 cargo(Rust 的构建工具和包管理器)来安装 Rust 是最简单的方法。

  1. 访问 Rust 官网 并根据你的操作系统下载安装程序。
  2. 运行安装程序并按照提示完成安装。新建一个文件夹然后用 vscode 打开,在终端执行下面的命令,然后耐心等待就可以了。 curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

image.png

image.png

image.png

  1. 打开命令提示符 (CMD) ,运行 cargo --versionrustc --version 来验证安装是否成功。这里强调,再强调,使用的是 CMD 而不是刚才下载的 shell 环境。

image.png

编写第一个 Rust 程序

下面将编写一个简单的命令行程序,它接收用户输入并输出一条欢迎信息。

  1. 创建新项目:在 CMD 中运行 cargo new hello_rust 命令来创建一个新的 Rust 项目。

image.png

2. **编写代码**:使用编辑器打开 `hello_rust` 目录下的 `src/main.rs` 文件,并写入以下代码:

image.png

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);
}
  1. 运行程序:在 hello_rust 目录下,(CMD 环境下)运行 cargo run 来构建并运行程序。程序会等待你输入名字,然后输出欢迎信息。

image.png

理解 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 程序。继续探索 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 项目。

  1. 在 CMD 终端中,安装 wasm-pack
cargo install wasm-pack
  1. 在 CMD 终端中,使用 wasm-pack 创建新项目:
wasm-pack new rust-wasm

image.png

  1. 进入项目目录:
cd rust-wasm
  1. 在 CMD 终端中,构建项目:
wasm-pack build --target web

这将生成一个 pkg 目录,包含编译后的 Wasm 二进制文件和 JavaScript 包装器。

image.png

步骤 3:在 React 应用中使用 Rust Wasm 模块

(首先使用 create-react-app 快速创建一个前端项目)

  1. 将 rust-wasm 整个文件夹复制到前端项目的根目录下,在 React 应用中安装生成的 Wasm 包:
yanr add ./rust-wasm/pkg

image.png

这里一定要注意是 相对路径!!! 安装成功之后就可以在 node_modules 中看到了:

image.png

注意!从命令中不难看出来,实际上我们在前端中用到的只是 ./rust-wasm/pkg 中的内容,因此没有必要将整个项目都复制过来,只需复制 ./rust-wasm/pkg 目录即可。

  1. 在 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 出现,则上面所有的步骤成功。

image.png

步骤 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 项目中。

  1. 在 Rust 项目目录中运行:
wasm-pack build --target web
  1. 将打包好的项目重新复制到前端项目,并按照刚才的步骤进行安装。
yanr add ./rust-wasm/pkg
  1. 回到 React 应用,运行开发服务器:
yarn start
  1. 将加载结果打印出来,不难看到这个时候已经挂载上我们新增的函数了

image.png

image.png

  1. 尝试执行的效果如下:

image.png

注意事项

  • 确保 Rust 项目中的 Cargo.toml 文件包含 wasm-bindgen 依赖。
  • 测试 Rust 和 React 之间的接口,确保类型正确转换。

3. 使用 Rust 编写第一个有意义的 Web Assembly 并在 React 中使用

要实现这个功能,我们将分为两个主要步骤进行:

步骤 1:使用 Rust 编写 WebAssembly 模块

首先,我们将创建一个 Rust 项目,该模块将加载图像、将其转换为灰度,然后返回图像数据的Base64编码。

  1. 设置 Rust Wasm 项目

使用 wasm-pack 创建一个新的 Rust Wasm 项目:

wasm-pack new rust-image-processor

进入项目目录:

cd rust-image-processor
  1. 添加依赖

Cargo.toml 文件中,添加必要的依赖,如 web-syswasm-bindgenimage

[dependencies]
wasm-bindgen = "0.2"  
web-sys = "0.3"  
wasm-bindgen-futures = "0.4"
image = "0.23"
console_log = "0.2"  
log = "0.4"

image.png

  1. 编写 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();  
}
  1. 构建 Rust Wasm 模块
wasm-pack build --target web

步骤 2:在 React 应用中使用 Rust Wasm 模块

  1. 安装生成的 Wasm 包
yarn add ./rust-image-processor/pkg
  1. 在 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显示出来。