Rust 中如何实现结构体某一字段是可选函数(带泛型的那种)
Rust 中如何实现结构体某一字段是可选函数(带泛型的那种)#
我想简单实现一种缓存,在创建该缓存时,有一个可选的函数,这个函数会在缓存中某一个 key 过期时被回掉,我试了好几种写法,编译无法通过,下面是代码示例
use std::collections::{LinkedList, HashMap};
use std::fmt::{Debug, Formatter};
#[derive(Debug, Default)]
pub(crate) struct Cache<T, F> where F: Fn(String, T) {
cache: HashMap<String, T>,
on_evicted: Option<F>,
}
impl<T, F> Cache<T, F> where F: Fn(String, T) {
fn new() -> Cache<T, F> {
Cache {
cache: HashMap::new(),
on_evicted: None,
}
}
fn new_with_evicted(callback: F) -> Cache<T, F> {
Cache {
cache: HashMap::new(),
on_evicted: Some(callback),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new() {
let cache: Cache<String, _> = Cache::new();
}
执行 cargo check
是可以通过的,但是运行 cargo test
就会报错,因为这个 on_evicted 是可选的,如何在 new 的时候指定泛型,或者不报错就好。哪怕不使用泛型来实现,我这个需求都行!求助了
报错如下:
error[E0284]: type annotations needed: cannot satisfy `<_ as FnOnce<(String, String)>>::Output == ()`
--> src/lru.rs:34:39
|
12 | fn new() -> Cache<T, F> {
| ----------------------- required by `lru::Cache::<T, F>::new`
...
34 | let cache: Cache<String, _> = Cache::new();
| ^^^^^^^^^^ cannot satisfy `<_ as FnOnce<(String, String)>>::Output == ()`
纠正下自己,不是编译不能通过,而是运行时当使用者不想要这个回调函数的时候,不知道如何去声明
把
F: Fn(String, T)
类型参数去掉吧,直接用&dyn Fn(String, T) -> ()
参数类型。可以看一下这里:stackoverflow.com/questions/363906...
从代码和说明上看,结构体的泛型参数实现了闭包的 Trait。有点绕,简单点理解,即泛型参数实现了多态,那么在实例对象时 (消费时) 指定泛型参数时,需要动态分配具体的类型。即楼上大哥的写法。