Rust从入门到实战系列一百四十三:Cacher 实现的限制

值缓存是一种更加广泛的实用行为,我们可能希望在代码中的其他闭包中也使用他们。然而,目前
Cacher 的实现存在两个小问题,这使得在不同上下文中复用变得很困难。
第一个问题是 Cacher 实例假设对于 value 方法的任何 arg 参数值总是会返回相同的值。也就是说,这
个 Cacher 的测试会失败:

struct Cacher

where

T: Fn(u32) -> u32,

{

calculation: T,

value: Option,

}

impl Cacher

where

T: Fn(u32) -> u32,

{

fn new(calculation: T) -> Cacher {

Cacher {

calculation,

value: None,

}

}

fn value(&mut self, arg: u32) -> u32 {

match self.value {

Some(v) => v,

None => {

let v = (self.calculation)(arg);

self.value = Some(v);

v

}

}

}

}

#[cfg(test)]

mod tests {

use super:😗;

#[test]
fn call_with_different_values() {
let mut c = Cacher::new(|a| a);
let v1 = c.value(1);
let v2 = c.value(2);
assert_eq!(v2, 2);
}

}

这个测试使用返回传递给它的值的闭包创建了一个新的 Cacher 实例。使用为 1 的 arg 和为 2 的 arg 调
用 Cacher 实例的 value 方法,同时我们期望使用为 2 的 arg 调用 value 会返回 2。
使用示例 13-9 和示例 13-10 的 Cacher 实现运行测试,它会在 assert_eq! 失败并显示如下信息:
$ cargo test
Compiling cacher v0.1.0 (file:///projects/cacher)
Finished test [unoptimized + debuginfo] target(s) in 0.72s
Running unittests (target/debug/deps/cacher-074d7c200c000afa)
running 1 test
test tests::call_with_different_values … FAILED
failures:
---- tests::call_with_different_values stdout ----
thread ‘main’ panicked at ‘assertion failed: (left == right)
left: 1,
right: 2’, src/lib.rs:43:9
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
failures:
tests::call_with_different_values
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
error: test failed, to rerun pass ‘–lib’
这里的问题是第一次使用 1 调用 c.value,Cacher 实例将 Some(1) 保存进 self .value。在这之后,无论
传递什么值调用 value,它总是会返回 1。
尝试修改 Cacher 存放一个哈希 map 而不是单独一个值。哈希 map 的 key 将是传递进来的 arg 值,而
value 则是对应 key 调用闭包的结果值。相比之前检查 self .value 直接是 Some 还是 None 值,现在
value 函数会在哈希 map 中寻找 arg,如果找到的话就返回其对应的值。如果不存在,Cacher 会调用
闭包并将结果值保存在哈希 map 对应 arg 值的位置。
当前 Cacher 实现的第二个问题是它的应用被限制为只接受获取一个 u32 值并返回一个 u32 值的闭包。
比如说,我们可能需要能够缓存一个获取字符串 slice 并返回 usize 值的闭包的结果。请尝试引入更多泛
型参数来增加 Cacher 功能的灵活性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值