【问题标题】:Borrowing in Rust closure借用 Rust 闭包
【发布时间】:2022-12-01 04:18:44
【问题描述】:

我有一个相当简单的用例,我将自己的通用 KeyValuePair 结构存储在 Vector 中,声明如下:

#[derive(Eq, Ord, PartialEq, PartialOrd)]
pub struct KeyValuePair<TKey, TValue> {
    key : TKey,
    value : TValue
}
pub struct OtherStruct<TKey, TValue> 
where TKey : Hash + Eq + Ord
{
    values : Vec<KeyValuePair<TKey, TValue>>
}

这一切都很好,但我无法弄清楚如何在此设置中使用 Vector 的 binary_search_by_key 函数。无论我通过什么,所有权检查器似乎都会生气。我理解一些异常消息,但我仍然坚持如何完成我真正想要的。

我开始于:

match &self.values.binary_search_by_key(key, |kvp| kvp.key) {
    Ok(pos) => return self.values.get(*pos),
    Err(pos) => return None
}

这给了我错误:

error[E0507]: cannot move out of `kvp.key` which is behind a shared refere

这是有道理的;如所写,它必须移动返回值。所以我把回报改成了借:

match &self.values.binary_search_by_key(key, |kvp| &kvp.key) {

这个失败是因为闭包函数定义期望 TKey 作为返回类型,而不是 &TKey


^^^^^^^^ expected type parameter `TKey`, found `&TKey`

我的下一次尝试是借用参数以避免移动,但我得到了这个:


match &self.values.binary_search_by_key(key, |&kvp| kvp.key) {
|                                             ^---
|                                             ||
|                                             |data moved here
|                                             |move occurs because `kvp` has type `KeyValuePair<TKey, TValue>`, which does not implement the `Copy` trait
|                                             help: consider removing the `&`: `kvp`

这个对我来说没有任何意义;我不明白为什么借用 kvp 会导致移动?是不是相反——它通常会移动,但是添加和借用呢?

在不破坏所有权的情况下按键搜索向量的正确语法是什么?

【问题讨论】:

    标签: rust borrow-checker


    【解决方案1】:

    将来,请提供您的整个功能定义。

    我认为它是这样的:

    impl<TKey, TValue> OtherStruct<TKey, TValue>
    where TKey : Hash + Eq + Ord
    {
        fn get(&self, key: &TKey) -> Option<&KeyValuePair<TKey, TValue>> {
            match self.values.binary_search_by_key(key, |kvp| &kvp.key) {
                Ok(pos) => return self.values.get(pos),
                Err(pos) => return None
            }
        }
    }
    

    类型不匹配是在传递给binary_search_by_key 的第一个和第二个参数之间。

    pub fn binary_search_by_key<'a, B, F>(
        &'a self,
        b: &B,
        f: F
    ) -> Result<usize, usize>
    where
        F: FnMut(&'a T) -> B,
        B: Ord,
    

    它期望第一个参数的类型为&amp;B,闭包返回类型为B。因此,由于您需要从闭包中返回 &amp;TKey,因此您需要将 &amp;&amp;TKey 作为第一个参数传递:

    impl<TKey, TValue> OtherStruct<TKey, TValue>
    where TKey : Hash + Eq + Ord
    {
        fn get(&self, key: &TKey) -> Option<&KeyValuePair<TKey, TValue>> {
            match self.values.binary_search_by_key(&key, |kvp| &kvp.key) {
                Ok(pos) => self.values.get(pos),
                Err(pos) => None
            }
        }
    }
    

    您也根本不需要 returns。

    playground

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多