跳至主要內容
rust 随笔(三)

rust 随笔(三)

thiserror

这篇文章探讨一个常见的错误处理库——thiserror 首先我们回顾一下上一篇的Error第二种用法:

#[derive(Debug)]
pub enum AppError {
    Config(ConfigError),
    Database(DatabaseError),
    Query(QueryError),
    Io(io::Error), // 有时也可能直接暴露一些通用的 IO 错误
    Initialization(String), // 其他初始化错误
}

impl fmt::Display for AppError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            AppError::Config(err) => write!(f, "{}", err), // 直接调用 ConfigError 的 Display
            AppError::Database(err) => write!(f, "{}", err), // 直接调用 DatabaseError 的 Display
            AppError::Query(err) => write!(f, "{}", err),
            AppError::Io(err) => write!(f, "IO 错误: {}", err),
            AppError::Initialization(msg) => write!(f, "初始化错误: {}", msg),
        }
    }
}

impl Error for AppError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        match self {
            AppError::Config(err) => Some(err),    // ConfigError 实现了 Error,可以作为 source
            AppError::Database(err) => Some(err),  // DatabaseError 实现了 Error
            AppError::Query(err) => Some(err),     // QueryError 实现了 Error
            AppError::Io(err) => Some(err),        // io::Error 本身就实现了 Error
            AppError::Initialization(_) => None,
        }
    }
}

// 实现 From trait
impl From<ConfigError> for AppError {
    fn from(err: ConfigError) -> Self {
        AppError::Config(err)
    }
}

impl From<DatabaseError> for AppError {
    fn from(err: DatabaseError) -> Self {
        AppError::Database(err)
    }
}

impl From<QueryError> for AppError {
    fn from(err: QueryError) -> Self {
        AppError::Query(err)
    }
}

impl From<io::Error> for AppError { // 有时也希望直接转换IO错误
    fn from(err: io::Error) -> Self {
        AppError::Io(err)
    }
}

Mr.Lexon大约 4 分钟rustrustthiserror
rust 随笔(二)

rust 随笔(二)

这篇文章探讨在Rust中自定义Error如何设计,我们先直接给出一个例子:

use std::fmt;

#[derive(Debug)]
enum CustomError {
    CustomErrorKind1,
    CustomErrorKind2(String),
    CustomErrorKind3(String, String),
}
//实现Display,用于呈现错误结构
impl fmt::Display for CustomError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            CustomError::CustomErrorKind1 => write!(f, "Custom Error Type 1 Occurred"),
            CustomError::CustomErrorKind2(s) => write!(f, "Custom Error Type 2 Occurred: {}", s),
            CustomError::CustomErrorKind3(s1, s2) => write!(f, "Custom Error Type 3 Occurred: {} - {}", s1, s2),
        }
    }
}

//通用化
impl std::error::Error for CustomError {}

// Example of how to use it:
fn main() {
    let error1 = CustomError::CustomErrorKind1;
    let error2 = CustomError::CustomErrorKind2("Something went wrong".to_string());
    let error3 = CustomError::CustomErrorKind3("File not found".to_string(), "Ensure the path is correct".to_string());

    println!("{}", error1);
    println!("{}", error2);
    println!("{}", error3);

    // For debug formatting
    println!("{:?}", error1);
    println!("{:?}", error2);
    println!("{:?}", error3);
}

Mr.Lexon大约 8 分钟rustrust
rust随笔(一)

rust随笔(一)

最近将《the book》看到了闭包部分,感触良多,发现rust的设计其实和oop关系不大,并且“组合优于继承”这句话不仅仅只是和结构体说的,还是对函数说的。本篇探讨一下问题:

  1. 何为生命周期
  2. rust和代码整洁之道有什么关系
  3. 为什么说学好组合子就学会了rust基本思想了

何为生命周期

我这里不从具体的函数定义出发,我从闭包出发,在定义中,闭包有以下trait

trait Fn;
trait FnOnce;
trait FnMut;

Mr.Lexon大约 14 分钟rustrustfunctional-program
没有依赖注入的世界:Monad、组合子与错误的自治逻辑

没有依赖注入的世界:Monad、组合子与错误的自治逻辑

“如果一个函数能拥有上下文,它就不再是一个孤立的黑箱,而是一个自治的结构。”

在主流面向对象开发中,依赖注入(Dependency Injection)是一种核心技术,它帮助我们解耦组件、延迟依赖绑定、模拟测试环境。但当我逐步走向函数式编程(尤其是 Haskell 与 Rust)时,我意识到另一种更本质的依赖管理方式:依赖不是注入的,而是组合出来的

我通过使用monad得出来一个有趣的结论,就是monad是一个组合上下文的工具,而Monad B里面的B则是上下文携带的变量类型,如果将其动起来,那么B的指向就是依赖本身,我们再将其广义起来,上下文组合起来整个fp程序


Mr.Lexon小于 1 分钟functional-programhaskell
Hoare逻辑

Hoare逻辑

简介

Hoare逻辑(Hoare Logic)是一种被广泛应用的工具。由英国计算机科学家C.A.R. Hoare于20世纪60年代提出,Hoare逻辑通过引入前置条件和后置条件的形式化描述,为程序的部分正确性提供了系统化的证明方法。Hoare逻辑的优势在于其简洁和高效。通过明确的前置条件和后置条件,开发者可以对程序的行为进行描述和验证。

三元组

三元组是Hoare逻辑的核心,其中P表示前置条件,Q表示后置条件,C表示程序或程序片段。

{P} C {Q}

Mr.Lexon大约 6 分钟proofproofformal-proof
形式化

形式化以及函数式编程

这个分区用于函数式编程以及形式化的研究笔记存储。


Mr.Lexon小于 1 分钟proofproof
页面配置

rust嵌入式开发-蜂鸣器

这几天突然对嵌入式有了兴趣,但是又不想接触C语言和C++的大坑(主要是arduino的引导坏了,程序无法烧录进去,不会修),后面发现rust正在逐渐支持嵌入式开发,所以来尝试一手。

提示

主要器件以及依赖: 器件:

  1. 芯片:stm32f103c8t6
  2. 无源蜂鸣器
  3. led二极管
  4. 1K电阻

软件依赖:

  1. rust 1.85.0-nightly
  2. cortex-m =
  3. cortex-m-rt = "0.7.5"
  4. cortex-m-semihosting = "0.5"
  5. panic-halt = "1.0.0"
  6. stm32f1xx-hal =
  7. openocd 0.12.0+dev-01557-gdd1758272-dirty
  8. arm-none-eabi-addr2line 2.36.1

Mr.Lexon大约 6 分钟embeddedembeddedrust
基于容器化Jenkins的cicd环境配置

基于容器化Jenkins的ci/cd环境配置

提示

开发环境: nixos 24.05 docker 24.0.5 Jenkins 2.479.1 nginx 1.27.2 gitea 1.22.3

部署环境: ubuntu 22.04 docker 24.0.5

初始化环境

创建目录

mkdir -p local-ci-cd/gitea
mkdir -p local-ci-cd/Jenkins
mkdir -p local-ci-cd/nginx
cd local-ci-cd

Mr.Lexon大约 2 分钟environmentci/cdJenkinsenv-configuration
基于bind9建立本地dns服务(docker)

基于bind9建立本地dns服务(docker)

重要

部署环境: ubuntu 20.04 docker 24.0.7 ubuntu/bind9 9.18.28

配置完之后如果出现错误请看”补充“可以更快得解决问题

## 初始化配置 ### 创建文件夹: ``` sh mkdir dns-server mkdir dns-server/config mkdir dns-server/data ``` ### 然后创建`docker-compose`文件 ``` bash touch docker-compose.yml ``` ### 编辑文件: ``` bash version: "3.3"

Mr.Lexon大约 4 分钟environmentdockerbind9dnsubuntuenv-configuration
Solana本地开发环境构建

Solana本地开发环境构建

首先默认已安装Anchor,solana-cli,rust.

创建钱包

使用以下命令创建钱包:

solana-keygen new --outfile ~/my-local-wallet.json

Mr.Lexon大约 1 分钟blockchainSolanarust