arrays - 尝试 const 数组中的 .find() 值时如何修复 "temporary value dropped here while still borrowed"?

标签 arrays rust iterator

我有一个以常量形式定义的数组,在任何函数之外:

const VALUES: [(char, &str); 2] = [('A', "abc"), ('B', "acb")];

我正在尝试使用 find() 方法位于 Iterator , 为了根据谓词从数组中提取单个元素:

VALUES.iter().find(|&&(name, _)| name == 'A');

在这种形式下,它工作正常。但是,一旦我尝试创建 let,我就无法将找到的元素评估为任何东西。绑定(bind),尝试绑定(bind)结果,根据文档,结果应该作为 Option<T> 返回.

让我们将第二行更改为不起作用的行:

const VALUES: [(char, &str); 2] = [('A', "abc"), ('B', "acb")];

fn main() {
    let result = VALUES.iter().find(|&&(name, _)| name == 'A');
}

( Playground )

人们会期望这会返回 Option<T>根据文档,但我得到了一个编译错误:

error: borrowed value does not live long enough
 --> src/main.rs:4:63
  |
4 |     let result = VALUES.iter().find(|&&(name, _)| name == 'A');
  |                  ------ temporary value created here          ^ temporary value dropped here while still borrowed
5 | }
  | - temporary value needs to live until here
  |
  = note: consider using a `let` binding to increase its lifetime

我完全糊涂了;我确定我刚刚搞砸了“借用检查器”。也许有人可以指出我正确的方向?

最佳答案

问题在于您将该数组转换为迭代器的具体方式。

首先,Rust 中的 const 实际上并不存在于任何地方。相反,它们在使用它们的任何地方都被值替换。因此,每次您使用常量时,您都会得到它的一个新副本。

其次,您正在使用 IntoIterator::into_iter。这将 按值 获取主题并将其转换为迭代器。

这些与第三部分相结合:IntoIterator 不是为固定大小的数组实现的。它仅针对指向固定大小数组的指针 实现。因此,为了调用 into_iter,编译器必须插入对调用者的自动借用。

所以,实际发生的是这样的:

let t = {
    // Make a new copy of `VALUES`.
    let values: [(char, &str); 5] = VALUES;
    // Borrow it.
    let values: &[_] = &values;
    // Call `into_iter` on the borrow.
    IntoIterator::into_iter(values).find(|&&(name, _)| name == 'A')
};

这会导致问题,因为编译器必须同时复制 借用 VALUES 以获得迭代器。与所有临时对象一样,所述副本的生命周期与语句一样长,但借用(通过绑定(bind)到变量)的生命周期必须长于该语句。

最好的解决方案是使 VALUES 成为数组的指针。这样可以防止复制整个数组;相反,您只需在每次使用时复制指针。

const VALUES: &[(char, &str)] = &[...];

或者,您可以显式复制 VALUES 并将其存储在变量中,然后在那个 上使用into_iter。但是,和以前一样,这会引入不必要的复制。

关于arrays - 尝试 const 数组中的 .find() 值时如何修复 "temporary value dropped here while still borrowed"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44614193/

相关文章:

python JSON只获取第一级的键

c++ - 创建抽象包装迭代器

c# - JSON 复杂类型,可以是对象或对象数组

ruby-on-rails - 需要帮助最大化多个相似对象中的 3 个因素并适当排序

arrays - 获取分块数组中项的组索引的算法

rust - 如何将异构类型放入 Rust 结构中

memory - 从编译为 Emscripten 的 Rust 获取 Javascript 中的数组

rust - 为什么 `const` 上的可变引用不是错误?

python - 检查列表中的值是否超过阈值一定次数并返回第一次超过的索引

python - 如何从python中的文本创建一个二维的句子单词数组?