You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中如何将Adapter结构体缓存抽象为Cache trait实现

重构方案

1. 扩展Cache Trait

首先给Cache trait添加缓存访问方法,让所有实现该trait的类型提供统一的访问接口,避免直接依赖内部结构:

pub trait Cache {
    // 保留原有插入方法
    fn insert(&mut self, data: Budgets) -> anyhow::Result<()>;
    // 添加获取预算的统一方法
    fn get(&self, budget_name: &str) -> Option<&Budget>;
}

2. 完善HashCache实现

让HashCache实现新增的get方法,封装内部HashMap的访问逻辑:

use std::collections::HashMap;

pub struct HashCache {
    cache: HashMap<String, Budget>,
}

impl Cache for HashCache {
    fn insert(&mut self, data: Budgets) -> anyhow::Result<()> {
        for budget in data.budgets.into_iter() {
            self.cache.insert(budget.name.clone(), budget);
        }
        Ok(())
    }

    fn get(&self, budget_name: &str) -> Option<&Budget> {
        self.cache.get(budget_name)
    }
}

// 给HashCache添加独立构造函数,简化实例创建
impl HashCache {
    pub fn new() -> Self {
        HashCache { cache: HashMap::new() }
    }
}

3. 泛化Adapter构造逻辑

让Adapter支持任意Cache实现,同时保留默认使用HashCache的快捷构造方式:

pub struct Adapter<'a, T: Cache> {
    base_uri: &'a str,
    client: reqwest::blocking::Client,
    default_budget: Option<&'a str>,
    cache: T,
}

// 通用构造逻辑:适配所有Cache类型
impl<'a, T: Cache> Adapter<'a, T> {
    // 自定义缓存的构造函数
    pub fn with_cache(bearer: String, cache: T) -> Self {
        let client = reqwest::blocking::Client::builder()
            .bearer_auth(bearer)
            .build()
            .expect("Failed to initialize HTTP client");
        
        Adapter {
            base_uri: "https://your-api-base-uri.com", // 替换为实际API地址
            client,
            default_budget: None,
            cache,
        }
    }

    // 重构show_accounts,通过Cache trait方法访问数据,消除嵌套调用
    pub fn show_accounts(&self, budget_name: &str) {
        match self.cache.get(budget_name) {
            Some(budget) => {
                if let Some(accounts) = &budget.accounts {
                    println!("{:?}", accounts);
                } else {
                    println!("No accounts present");
                }
            }
            None => println!("Budget '{}' not found in cache", budget_name),
        }
    }
}

// 默认构造函数:使用HashCache作为缓存
impl<'a> Adapter<'a, HashCache> {
    pub fn new(bearer: String) -> Self {
        Self::with_cache(bearer, HashCache::new())
    }
}

可选:动态分发模式(无泛型参数)

如果不想让Adapter携带泛型参数,可使用Box<dyn Cache>实现动态分发,更接近传统“接口”模式:

pub struct Adapter<'a> {
    base_uri: &'a str,
    client: reqwest::blocking::Client,
    default_budget: Option<&'a str>,
    cache: Box<dyn Cache>,
}

impl<'a> Adapter<'a> {
    pub fn new(bearer: String) -> Self {
        Self::with_cache(bearer, Box::new(HashCache::new()))
    }

    pub fn with_cache(bearer: String, cache: Box<dyn Cache>) -> Self {
        let client = reqwest::blocking::Client::builder()
            .bearer_auth(bearer)
            .build()
            .expect("Failed to initialize HTTP client");
        
        Adapter {
            base_uri: "https://your-api-base-uri.com",
            client,
            default_budget: None,
            cache,
        }
    }

    pub fn show_accounts(&self, budget_name: &str) {
        match self.cache.get(budget_name) {
            Some(budget) => {
                if let Some(accounts) = &budget.accounts {
                    println!("{:?}", accounts);
                } else {
                    println!("No accounts present");
                }
            }
            None => println!("Budget '{}' not found in cache", budget_name),
        }
    }
}

使用示例

fn main() -> anyhow::Result<()> {
    // 使用默认HashCache
    let mut adapter = Adapter::new("your-bearer-token".to_string());
    
    // 模拟插入数据
    let budgets = Budgets { budgets: vec![Budget { name: "MyBudget".to_string(), accounts: Some(vec![]) }] };
    adapter.cache.insert(budgets)?;
    
    adapter.show_accounts("MyBudget");

    // 使用自定义缓存(比如自己实现的AnotherCache)
    // let custom_cache = AnotherCache::new();
    // let mut adapter = Adapter::with_cache("your-bearer-token".to_string(), custom_cache);
    
    Ok(())
}

内容的提问来源于stack exchange,提问作者seve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 06:40:43