rust - 使用 HRTB 自动化 getter 方法单元测试

标签 rust higher-rank-types

我在 Rust 中有一个“ View ”数据结构,其中包含对另一个数据结构的引用,并且我想自动测试在 View 数据结构上实现的 getter 方法。这是一个只有一个 getter 的 MRE:

/// View data structure.
struct View<'a> {
    value: &'a u32,
}
impl<'a> View<'a> {
    /// Getter method.
    pub fn value(&self) -> u32 {
        *self.value
    }
}

/// Attempt to automate unit testing of the getter: create an underlying value,
/// then create a `View`, then apply the getter method to the `View` and ensure
/// we get the expected value out.
fn check_getter(getter: fn(&View) -> u32) {
    let value: u32 = 7;
    let view = View { value: &value };
    assert!(getter(&view) == 7);
}
check_getter(View::value);

编译失败,出现以下错误:

mismatched types
expected fn pointer `for<'r, 's> fn(&'r tests::test_adcs::View<'s>) -> _`
   found fn pointer `for<'r> fn(&'r tests::test_adcs::View<'_>) -> _`

我认为我需要使用 HRTB,并尝试了各种排列,但无法编译任何内容。

最佳答案

TL;DR:使用闭包(如果您愿意,可以使用宏):

check_getter(|v| v.value());

你掉进了early-bound vs. late-bound lifetimes的陷阱.

View::value 没有有签名 for<'a> fn <View<'a>>::value() 。相反,它具有签名 fn <View<'some_concrete_lifetime>>::value() 。即'a不是任何生命周期,而是一些推断的生命周期。因此 HRTB 不起作用——只有一个生命周期与给定的函数匹配。 You can read more about early-bound and late-bound lifetimes in this recent answer I wrote ,但问题的关键在于,因为生命周期'a出现在 impl ,而不是函数本身,它会成为早期绑定(bind),并且对于函数的每个实例只有一个具体的生命周期,而不是后期绑定(bind)并允许与任何生命周期一起使用。

修复方法只是用一个闭包包裹它,使其成为后期绑定(bind)。

关于rust - 使用 HRTB 自动化 getter 方法单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73006849/

相关文章:

rust - 默认泛型参数

encryption - 如何为AES加密生成随 secret 钥?

python - 为什么 Python set 交集比 Rust HashSet 交集快?

haskell - 这个使用 RankNTypes 的仿函数叫什么名字?

haskell - 存在类型包装器的必要性

rust - 如何将临时字符串转换为 &str?

MongoDB Rust 客户端连接错误

haskell - Haskell 中的非法多态或限定类型

gadt - 数据构造器中的 Rank-2 类型

haskell - 'uncurry' 是否有可能是一个 forall 量词?