rust 在结构的字段中放置特征

new9mtju  于 2022-11-24  发布在  其他
关注(0)|答案(1)|浏览(109)

我是Rust的新手,我正在构建一个Adapter结构体,它有一个缓存来存储本地获取的数据。我已经成功地将其用于HashMap,但我想将其泛化,让用户将其替换为任何其他实现我的Cache Trait的类型。
如何将其重构为类似接口的实现?

pub trait Cache {
    fn insert(&mut self, data: Budgets) -> anyhow::Result<()>;
}

// #[derive(Debug)]
pub struct Adapter<'a, T: Cache> {
    base_uri: &'a str,
    client: reqwest::blocking::Client,
    default_budget: Option<&'a str>,
    //cache: HashMap<String, Budget>  <-- original impl
    //cache: &'a dyn Cache  <-- Not sure how to make this work
    cache: T
}

我能够得到一个hacky解决方案,我使用上面的未注解代码,然后为我的特征创建一个新的结构:

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(())
    }
}

这就要求我创建一个需要具体类型参数的脏new方法:

impl<'a> Adapter<'a,  HashCache> {
    pub fn new(bearer: String) -> Self {
       // -- other fields --
            //cache: HashMap::new()
            cache: HashCache { cache: HashMap::new() }
        }
    }

现在我必须遍历一个结构体,遍历该高速缓存有一个额外的问题:

pub fn show_accounts(&self, budget_name: &str) {
        if let Some(b) = self.cache.cache.get(budget_name) {  <-- Requires getting into the struct
            if let Some(a) = &b.accounts {
                println!("{:?}", a)
            } else {
                println!{"No accounts present"}
            }
        }
    }
dnph8jn4

dnph8jn41#

由于您在crate中定义了Cache,因此应该可以直接在HashMap上实现该特征:

impl Cache for HashMap<String, Budget> {
    // ...
}

为了避免“脏的新方法”问题,您还可以要求该类型实现Default,因此您可以编写例如:

impl<'a, T: Cache + Default> Adapter<'a, T> {
    pub fn new(bearer: String) -> Self {
            // -- other fields --
            cache: T::default()
        }
    }
}

对于show_accounts(),因为使用的是泛型T,所以不应该硬编码HashMap方法,而是将这些方法添加到Cache特征中:

pub trait Cache {
    fn get(s: String) -> Option<Budget>;
    fn insert(&mut self, data: Budgets) -> anyhow::Result<()>;
    // -- other methods --
}

相关问题