人人都会AI编程

参数传递、返回值接收、错误捕获

更新时间:2026-07-11

1. 参数传递

Rust 命令可以接收基本类型(如 Stringi32bool)或序列化结构体作为参数。前端调用时传入一个 JSON 对象,Tauri 会自动反序列化成对应的 Rust 类型。

Rust 端定义命令

#[tauri::command]
fn greet(name: String, age: u32) -> String {
    format!("Hello, {}! You are {} years old.", name, age)
}

前端调用(使用 @tauri-apps/api):

import { invoke } from '@tauri-apps/api/core';

const result = await invoke('greet', { name: 'Alice', age: 30 });
console.log(result); // "Hello, Alice! You are 30 years old."

如果参数较多或结构固定,建议使用结构体:

#[derive(serde::Deserialize)]
struct User {
    name: String,
    age: u32,
}

#[tauri::command]
fn process_user(user: User) -> String {
    format!("{} is {} years old", user.name, user.age)
}

前端只需传递与结构体字段匹配的对象即可,字段名必须一致(默认骆驼式命名)。


2. 返回值接收

命令的返回值类型会被自动序列化成 JSON,前端 invoke 返回一个 Promise,解析后得到对应的 JavaScript 值。

  • 基本类型i32numberStringstringVec<T>Array 等。
  • 复杂类型:只要实现了 Serialize,就能返回自定义结构体。

示例——返回一个结构体:

#[derive(serde::Serialize)]
struct FileInfo {
    path: String,
    size: u64,
}

#[tauri::command]
fn get_file_info(path: String) -> FileInfo {
    // 假设获取到了信息
    FileInfo { path, size: 1024 }
}

前端:

const fileInfo = await invoke<FileInfo>('get_file_info', { path: '/test.txt' });
console.log(fileInfo.size); // 1024

注意:你可以为 invoke 显式指定泛型类型,以获得更准确的 TypeScript 推导。


3. 错误捕获

Rust 命令中推荐返回 Result<T, E>,其中 E 可以是任何实现了 Serialize 的错误类型。Tauri 会自动将 Ok 值作为正常返回值,而 Err 值会被序列化后以 JavaScript 异常的形式抛出。

Rust 端

#[tauri::command]
fn divide(a: i32, b: i32) -> Result<i32, String> {
    if b == 0 {
        Err("Division by zero".into())
    } else {
        Ok(a / b)
    }
}

前端错误处理

try {
    const result = await invoke('divide', { a: 10, b: 0 });
    console.log(result);
} catch (error) {
    console.error(error); // "Division by zero"
}

你也可以定义更结构化的错误:

#[derive(Debug, serde::Serialize)]
struct MyError {
    code: u32,
    message: String,
}

#[tauri::command]
fn do_something() -> Result<(), MyError> {
    Err(MyError { code: 1, message: "Something went wrong".into() })
}

前端捕获到的 error 将是一个包含 codemessage 的字符串或对象(取决于序列化方式),你可以解析它并进行针对性处理。


实用要点

  • 参数校验:Rust 的类型系统已强制校验,错误的数据类型会导致调用当场失败(Promise reject)。
  • 命令注册:所有命令需要通过 .invoke_handler(tauri::generate_handler![greet, divide]) 注册到主构建器中,否则前端无法调用。
  • 异步命令:如果命令内部需要执行耗时操作(如网络请求),可以定义为异步函数 async fn,避免阻塞主线程。前端调用方式不变,仍然是 await invoke(...)

通过这种方式,Tauri 让前后端之间的数据交换和错误传递变得高度统一——就像调用一个本地函数,只不过它跑在另一个进程里,但你几乎感知不到中间的序列化与 IPC 细节。