Rust错误处理库thiserror-nostd-notrait的使用,支持无标准库和无trait的轻量级错误处理
Rust错误处理库thiserror-nostd-notrait的使用,支持无标准库和无trait的轻量级错误处理
示例
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
pub enum DataStoreError {
#[error("data store disconnected")]
Disconnect(#[from] io::Error),
#[error("the data for key `{0}` is not available")]
Redaction(String),
#[error("invalid header (expected {expected:?}, found {found:?})")]
InvalidHeader {
expected: String,
found: String,
},
#[error("unknown data store error")]
Unknown,
}
完整示例代码
// 在no_std环境下的使用示例
#![no_std]
use core::fmt;
use thiserror_nostd_notrait::Error;
#[derive(Error, Debug)]
pub enum CustomError {
#[error("Invalid value: {0}")]
InvalidValue(u32),
#[error("Operation failed")]
OperationFailed,
#[error("Nested error: {0}")]
NestedError(#[from] OtherError),
}
#[derive(Debug)]
pub struct OtherError;
impl fmt::Display for OtherError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Other error occurred")
}
}
fn main() {
let err = CustomError::InvalidValue(42);
println!("Error: {}", err); // 输出: Error: Invalid value: 42
let nested_err = CustomError::NestedError(OtherError);
println!("Nested error: {}", nested_err); // 输出: Nested error: Other error occurred
}
使用说明
- 在Cargo.toml中添加依赖:
[dependencies]
thiserror = { version = "1.0", package = "thiserror-nostd-notrait" }
- 主要特点:
- 支持
no_std
环境 - 不强制要求实现
Error
trait - 可以自动生成
Display
实现 - 支持从其他错误类型转换
- 支持错误消息格式化
- 消息格式化支持:
#[error("{var}")]
→write!("{}", self.var)
#[error("{0}")]
→write!("{}", self.0)
#[error("{var:?}")]
→write!("{:?}", self.var)
#[error("{0:?}")]
→write!("{:?}", self.0)
- 编译器要求:Rust 1.56+
与标准thiserror的区别
这个fork版本在no_std
环境下不自动派生Error
trait,但仍然保留了其他功能如Display
实现、错误转换等。适用于需要在无标准库环境中使用thiserror功能的场景。
1 回复
Rust错误处理库thiserror-nostd-notrait的使用指南
简介
thiserror-nostd-notrait
是thiserror
的一个变体版本,专为无标准库(no_std)和无trait对象的环境设计。它提供了轻量级的错误处理能力,适用于嵌入式系统和其他资源受限的环境。
主要特性
- 支持
no_std
环境 - 不依赖trait对象
- 轻量级实现
- 保留
thiserror
的主要语法和功能
使用方法
基本安装
在Cargo.toml
中添加依赖:
[dependencies]
thiserror-nostd-notrait = "0.1"
基础示例
#![no_std]
use thiserror_nostd_notrait as thiserror;
#[derive(thiserror::Error, Debug)]
enum MyError {
#[error("invalid value: {0}")]
InvalidValue(i32),
#[error("operation timed out")]
Timeout,
#[error("I/O error")]
Io,
}
fn might_fail(value: i32) -> Result<(), MyError> {
if value < 0 {
Err(MyError::InvalidValue(value))
} else {
Ok(())
}
}
嵌套错误处理
#[derive(thiserror::Error, Debug)]
enum ApiError {
#[error("network error: {0}")]
Network(#[from] NetworkError),
#[error("parsing error: {0}")]
Parse(#[from] ParseError),
}
#[derive(thiserror::Error, Debug)]
enum NetworkError {
#[error("connection failed")]
ConnectionFailed,
}
#[derive(thiserror::Error, Debug)]
enum ParseError {
#[error("invalid format")]
InvalidFormat,
}
自定义错误上下文
#[derive(thiserror::Error, Debug)]
enum CustomError {
#[error("failed with code {code}: {message}")]
OperationFailed {
code: u32,
message: &'static str,
},
#[error("configuration error in {file} at line {line}")]
ConfigError {
file: &'static str,
line: u32,
},
}
完整示例demo
下面是一个完整的嵌入式应用示例,展示了thiserror-nostd-notrait
在实际项目中的使用:
#![no_std]
use thiserror_nostd_notrait as thiserror;
use core::fmt;
// 定义硬件相关错误
#[derive(thiserror::Error, Debug)]
enum HardwareError {
#[error("sensor {id} initialization failed")]
SensorInitFailed { id: u8 },
#[error("communication timeout with device {0}")]
DeviceTimeout(u8),
#[error("invalid register value: {0}")]
InvalidRegister(u8),
}
// 定义应用逻辑错误
#[derive(thiserror::Error, Debug)]
enum AppError {
#[error("hardware failure: {0}")]
Hardware(#[from] HardwareError),
#[error("invalid configuration")]
ConfigError,
#[error("operation not allowed in current state")]
InvalidState,
}
// 模拟硬件初始化函数
fn init_sensor(sensor_id: u8) -> Result<(), HardwareError> {
if sensor_id > 5 {
Err(HardwareError::SensorInitFailed { id: sensor_id })
} else {
Ok(())
}
}
// 模拟应用逻辑函数
fn startup_sequence() -> Result<(), AppError> {
init_sensor(3)?; // 使用?操作符自动转换错误类型
init_sensor(7)?; // 这会返回错误
Ok(())
}
// 实现简单的日志输出(在no_std环境中)
fn log_error(err: &impl fmt::Debug) {
// 在实际嵌入式系统中,这里可能是串口输出或其他日志机制
// 这里只是演示错误处理流程
}
fn main() {
match startup_sequence() {
Ok(_) => (),
Err(e) => {
log_error(&e);
// 根据错误类型执行不同的恢复逻辑
match e {
AppError::Hardware(hw_err) => {
// 处理硬件错误
},
_ => {
// 处理其他错误
}
}
}
}
}
注意事项
- 由于是
no_std
环境,某些功能如std::error::Error
trait不可用 - 错误消息必须是编译时常量(
&'static str
) - 相比标准
thiserror
,功能有所精简以保持轻量
适用场景
- 嵌入式系统开发
- 操作系统内核开发
- 需要极致轻量级的应用
- 无法或不想使用trait对象的场景
性能特点
thiserror-nostd-notrait
相比标准thiserror
:
- 编译后二进制更小
- 内存占用更低
- 不包含动态分发开销
- 适合对资源要求严格的场景