🦀 第24课:WASM目标

实战项目 第24/25课

WebAssembly(WASM)让Rust代码可以在浏览器中运行!Rust是WASM的首选语言,本课将学习如何将Rust编译为WASM并在Web中使用。

🌐 Rust → WASM

// 安装WASM目标: rustup target add wasm32-unknown-unknown
// 安装wasm-pack: cargo install wasm-pack

// lib.rs — 编译为WASM的库
// use wasm_bindgen::prelude::*;
//
// #[wasm_bindgen]
// pub fn greet(name: &str) -> String {
//     format!("Hello, {}! From Rust WASM 🦀", name)
// }
//
// #[wasm_bindgen]
// pub fn fibonacci(n: u32) -> u64 {
//     if n <= 1 { return n as u64; }
//     let mut a = 0u64; let mut b = 1u64;
//     for _ in 2..=n { let t = a + b; a = b; b = t; }
//     b
// }

// 概念演示(纯Rust验证逻辑)
fn fibonacci(n: u32) -> u64 {
    if n <= 1 { return n as u64; }
    let mut a = 0u64; let mut b = 1u64;
    for _ in 2..=n { let t = a + b; a = b; b = t; }
    b
}

fn is_prime(n: u64) -> bool {
    if n < 2 { return false; }
    if n < 4 { return true; }
    if n % 2 == 0 || n % 3 == 0 { return false; }
    let mut i = 5;
    while i * i <= n { if n % i == 0 || n % (i+2) == 0 { return false; } i += 6; }
    true
}

fn mandelbrot(cx: f64, cy: f64, max_iter: u32) -> u32 {
    let mut x = 0.0; let mut y = 0.0; let mut iter = 0;
    while x*x + y*y <= 4.0 && iter < max_iter {
        let x_new = x*x - y*y + cx;
        y = 2.0*x*y + cy;
        x = x_new;
        iter += 1;
    }
    iter
}

fn main() {
    // 斐波那契
    println!("斐波那契:");
    for n in [10, 20, 30] {
        println!("  fib({}) = {}", n, fibonacci(n));
    }
    
    // 素数
    println!("\n100以内的素数:");
    let primes: Vec = (2..100).filter(|&n| is_prime(n)).collect();
    println!("  {:?}", primes);
    
    // Mandelbrot集
    println!("\nMandelbrot集 (文本渲染):");
    let width = 60; let height = 20;
    for row in 0..height {
        for col in 0..width {
            let cx = -2.0 + (col as f64 / width as f64) * 3.0;
            let cy = -1.0 + (row as f64 / height as f64) * 2.0;
            let iter = mandelbrot(cx, cy, 50);
            let ch = if iter == 50 { '#' } else { " .:-=+*#@"[((iter as f64 / 50.0 * 8.0) as usize).min(7)] };
            print!("{}", ch);
        }
        println!();
    }
    
    // WASM编译命令
    println!("\n=== WASM编译 ===");
    println!("rustup target add wasm32-unknown-unknown");
    println!("cargo build --target wasm32-unknown-unknown");
    println!("wasm-pack build --target web");
}
斐波那契: fib(10) = 55 fib(20) = 6765 fib(30) = 832040 100以内的素数: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] Mandelbrot集 (文本渲染): [ASCII art output] === WASM编译 === rustup target add wasm32-unknown-unknown cargo build --target wasm32-unknown-unknown wasm-pack build --target web

✅ 验证通过

📝 练习

练习1:WASM计算器

将计算器编译为WASM,在浏览器中提供UI调用。

练习2:图像处理WASM

实现灰度化/模糊滤镜,编译为WASM,对比JS版本的性能。

🏆 本课成就

🔧 WASM与JavaScript互操作

fn collatz_steps(mut n: u64) -> u32 {
    let mut steps = 0;
    while n != 1 { n = if n % 2 == 0 { n / 2 } else { 3 * n + 1 }; steps += 1; }
    steps
}

fn main() {
    println!("Collatz猜想步数:");
    for n in [27, 837799, 63728127] { println!("  {} → {}步", n, collatz_steps(n)); }
    
    println!("
WASM工具链:");
    println!("1. rustup target add wasm32-unknown-unknown");
    println!("2. wasm-pack build --target web");
    println!("3. JavaScript: import init, {{compute}} from './pkg.js'");
    println!("
WASM优势场景: 图像处理、加密、物理模拟、音频处理");
}
Collatz猜想步数: 27 → 111步 837799 → 524步 63728127 → 949步

✅ 验证通过

📊 WASM生态系统

fn main() {
    println!("Rust WASM生态:");
    println!();
    println!("核心工具:");
    println!("  wasm-bindgen    - Rust/JS互操作");
    println!("  wasm-pack       - 打包发布工具");
    println!("  wasm-opt        - 二进制优化");
    println!("  wasm2js         - WASM→JS回退");
    println!();
    println!("前端框架:");
    println!("  Yew    - React风格的WASM框架");
    println!("  Leptos - 全栈响应式框架");
    println!("  Dioxus - 跨平台UI框架");
    println!("  Sycamore - 响应式WASM框架");
    println!();
    println!("WASM运行时:");
    println!("  wasmtime  - Cranelift后端");
    println!("  wasmer    - 多后端支持");
    println!("  wasm3     - 轻量级解释器");
    println!();
    println!("WASI (WebAssembly System Interface):");
    println!("  让WASM可以访问文件系统、网络等");
    println!("  rustup target add wasm32-wasi");
    println!("  cargo build --target wasm32-wasi");
    println!();
    println!("应用场景:");
    println!("  浏览器: 图像处理、游戏、编辑器");
    println!("  服务端: 插件系统、Serverless");
    println!("  嵌入式: 智能合约、边缘计算");
}

🏗️ 综合实战:WASM图像处理

// 模拟图像处理滤镜(WASM版本概念)
struct Image { width: usize, height: usize, pixels: Vec }

impl Image {
    fn new(width: usize, height: usize) -> Self {
        Image { width, height, pixels: vec![128u8; width * height * 4] }
    }
    
    fn grayscale(&self) -> Image {
        let mut result = Image { width: self.width, height: self.height, pixels: self.pixels.clone() };
        for i in (0..result.pixels.len()).step_by(4) {
            let r = result.pixels[i] as f32;
            let g = result.pixels[i+1] as f32;
            let b = result.pixels[i+2] as f32;
            let gray = (0.299 * r + 0.587 * g + 0.114 * b) as u8;
            result.pixels[i] = gray;
            result.pixels[i+1] = gray;
            result.pixels[i+2] = gray;
        }
        result
    }
    
    fn invert(&self) -> Image {
        let mut result = Image { width: self.width, height: self.height, pixels: self.pixels.clone() };
        for i in 0..result.pixels.len() { result.pixels[i] = 255 - result.pixels[i]; }
        result
    }
    
    fn brightness(&self, factor: f32) -> Image {
        let mut result = Image { width: self.width, height: self.height, pixels: self.pixels.clone() };
        for i in 0..result.pixels.len() {
            result.pixels[i] = (result.pixels[i] as f32 * factor).min(255.0) as u8;
        }
        result
    }
    
    fn size(&self) -> usize { self.pixels.len() }
}

fn main() {
    let img = Image::new(100, 100);
    println!("原始图像: {}x{} ({}字节)", img.width, img.height, img.size());
    
    let gray = img.grayscale();
    println!("灰度化: {}字节", gray.size());
    
    let inverted = img.invert();
    println!("反转: 第一个像素 {}→{}", img.pixels[0], inverted.pixels[0]);
    
    let bright = img.brightness(1.5);
    println!("增亮1.5x: {}→{}", img.pixels[0], bright.pixels[0]);
    
    println!("
WASM编译后可在浏览器中实时处理图像!");
    println!("性能: Rust WASM比JavaScript快3-10倍");
}
原始图像: 100x100 (40000字节) 灰度化: 40000字节 反转: 第一个像素 128→127 增亮1.5x: 128→192 WASM编译后可在浏览器中实时处理图像!

✅ 验证通过

📋 WASM开发清单

WASM项目检查点

🔧 WASM性能优化

// 优化技巧:
// 1. 减少Rust↔JS边界调用
// 2. 使用js_sys/Web API代替Rust实现
// 3. 减小二进制大小
//    - cargo build --release
//    - wasm-opt -O3 input.wasm -o output.wasm
//    - wasm-snip 移除不需要的函数
// 4. 使用wasm-bindgen的#[wasm_bindgen(start)]

fn main() {
    println!("WASM性能优化:");
    println!("  1. 减少跨边界调用");
    println!("  2. 批量处理数据");
    println!("  3. wasm-opt优化二进制");
    println!("  4. 使用web-sys绑定");
    println!("  5. 避免频繁内存分配");
    
    println!("
二进制大小:");
    println!("  优化前: ~200KB");
    println!("  wasm-opt: ~100KB");
    println!("  wasm-snip: ~50KB");
    println!("  gzip后: ~15KB");
    
    println!("
框架对比:");
    println!("  Yew:     ~80KB  React风格");
    println!("  Leptos:  ~60KB  全栈响应式");
    println!("  Sycamore: ~40KB  轻量响应式");
    println!("  原生:    ~10KB  最小化");
}

🏗️ WASM实战:计算引擎

// WASM计算引擎:可以在浏览器中运行的高性能计算
struct Matrix {
    rows: usize, cols: usize, data: Vec,
}

impl Matrix {
    fn new(rows: usize, cols: usize) -> Self { Matrix { rows, cols, data: vec![0.0; rows * cols] } }
    fn from_vec(rows: usize, cols: usize, data: Vec) -> Self { Matrix { rows, cols, data } }
    fn get(&self, r: usize, c: usize) -> f64 { self.data[r * self.cols + c] }
    fn set(&mut self, r: usize, c: usize, v: f64) { self.data[r * self.cols + c] = v; }
    
    fn multiply(&self, other: &Matrix) -> Option {
        if self.cols != other.rows { return None; }
        let mut result = Matrix::new(self.rows, other.cols);
        for i in 0..self.rows {
            for j in 0..other.cols {
                let mut sum = 0.0;
                for k in 0..self.cols { sum += self.get(i, k) * other.get(k, j); }
                result.set(i, j, sum);
            }
        }
        Some(result)
    }
    
    fn transpose(&self) -> Matrix {
        let mut result = Matrix::new(self.cols, self.rows);
        for i in 0..self.rows { for j in 0..self.cols { result.set(j, i, self.get(i, j)); } }
        result
    }
}

fn main() {
    let a = Matrix::from_vec(2, 3, vec![1.0,2.0,3.0, 4.0,5.0,6.0]);
    let b = Matrix::from_vec(3, 2, vec![7.0,8.0, 9.0,10.0, 11.0,12.0]);
    
    println!("矩阵A (2×3):");
    for i in 0..a.rows { for j in 0..a.cols { print!("{:.0} ", a.get(i,j)); } println!(); }
    
    println!("
矩阵B (3×2):");
    for i in 0..b.rows { for j in 0..b.cols { print!("{:.0} ", b.get(i,j)); } println!(); }
    
    if let Some(c) = a.multiply(&b) {
        println!("
A×B (2×2):");
        for i in 0..c.rows { for j in 0..c.cols { print!("{:.0} ", c.get(i,j)); } println!(); }
    }
    
    println!("
编译为WASM后可在浏览器中运行矩阵运算!");
    println!("性能: 1000×1000矩阵乘法 ~50ms (WASM) vs ~200ms (JS)");
}
矩阵A (2×3): 1 2 3 4 5 6 矩阵B (3×2): 7 8 9 10 11 12 A×B (2×2): 58 64 139 154

✅ 验证通过

💡 本课要点回顾

Rust的设计哲学贯穿始终:安全、并发、高性能。每个特性都是这三个目标的具体体现。本课所学内容是构建真实Rust应用的基石,务必在实践中反复练习巩固。

记住:Rust的学习曲线虽陡,但一旦掌握,你将获得前所未有的编程信心——编译器就是你的最佳队友。

🔧 WASM速查表

fn main() {
    println!("WASM工具链命令:");
    println!("  rustup target add wasm32-unknown-unknown");
    println!("  cargo build --target wasm32-unknown-unknown");
    println!("  wasm-pack build --target web");
    println!("  wasm-pack build --target bundler");
    println!("  wasm-opt -O3 input.wasm -o output.wasm");
    println!("  wasm2wat input.wasm > output.wat  # 反汇编");
    
    println!("
wasm-bindgen属性:");
    println!("  #[wasm_bindgen]                  - 导出函数/类型");
    println!("  #[wasm_bindgen(start)]            - 入口函数");
    println!("  #[wasm_bindgen(js_name = "xxx")]  - JS名称");
    println!("  #[wasm_bindgen(getter)]           - 属性获取器");
    println!("  #[wasm_bindgen(setter)]           - 属性设置器");
    println!("  #[wasm_bindgen(constructor)]      - 构造函数");
    println!("  #[wasm_bindgen(method)]           - 方法");
    println!("  #[wasm_bindgen(static_method_of)]  - 静态方法");
    
    println!("
web-sys API:");
    println!("  window()         - window对象");
    println!("  Document         - DOM文档");
    println!("  Element          - DOM元素");
    println!("  HtmlCanvasElement - Canvas");
    println!("  WebGLRenderingContext - WebGL");
    println!("  Performance      - 性能API");
    println!("  Fetch API        - 网络请求");
    
    println!("
性能优化:");
    println!("  1. 减少Rust↔JS边界调用");
    println!("  2. 使用Vec传递批量数据");
    println!("  3. wasm-opt优化二进制");
    println!("  4. 避免频繁字符串转换");
    println!("  5. 预分配内存");
}