过滤器关闭时借用的时间不够长

gib*_*gib 2 lifetime rust

当我尝试编译此代码(playground)时:

fn main() {
    let iter = "abc123".chars().filter(&|&c: &char| c.is_digit(10));
    match iter.clone().take(3).count() {
        3 => println!("{}", iter.collect::<String>()),
        _ => {}
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

error: borrowed value does not live long enough
 --> test.rs:2:41
  |
2 |     let iter = "abc123".chars().filter(&|c: &char| c.is_digit(10));
  |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^ - temporary value only lives until here
  |                                         |
  |                                         temporary value created here
...
7 | }
  | - temporary value needs to live until here
  |
  = note: consider using a `let` binding to increase its lifetime
Run Code Online (Sandbox Code Playgroud)

我理解错误有助于告诉我在上面的行中用let f = &|c: &char| c.is_digit(10);(工作代码)声明闭包,但为什么这是必要的呢?

我也不确定为什么闭包必须包含两个引用 - &|c: &char|.不"abc123".chars()只是创建一个字符迭代器?

She*_*ter 5

但为什么这有必要呢?

我真的不知道如何解释它比错误消息更好:

temporary value only lives until here
temporary value created here
Run Code Online (Sandbox Code Playgroud)

您正在语句中创建临时值(闭包本身),然后引用它.当语句结束时,该值被销毁 - 没有任何东西拥有它!问题是代码试图保持对现在被破坏的值的引用.如果编译器允许这样做,那么当它使用该引用时,谁知道将访问哪些随机数据.

闭包必须包含两个引用

那么,它不具备对.filter(|c| c.is_digit(10))工作得很好; 类型推断允许c自动输入为&char.在&c只有图案匹配,并自动取消引用值.这是多余的,因为方法调用会自动取消引用.

更大的问题是,代码尝试(克隆包含关闭,你不能做一个迭代器1,2,3,4问一个问题)之前(善良,人拒绝搜索).你选择解决这个问题的聪明方法是克隆对闭包的引用,这很好.

问题循环回到引用语句末尾被销毁的东西.


如果目标是忽略所有非数字,跳过前3位数字然后收集其余数字,您可以使用Iterator::skip:

let iter = "abc123".chars().filter(|c| c.is_digit(10));
let together: String = iter.skip(3).collect();
println!("{}", together);
Run Code Online (Sandbox Code Playgroud)

如果目标是仅取前三位数,当且仅当有三位数时,我可能总是收集这些数字,并检查是否结束:

let mut iter = "abc123".chars().filter(|c| c.is_digit(10));
let together: String = iter.by_ref().take(3).collect();

if iter.next().is_none() {
    println!("{}", together);
}
Run Code Online (Sandbox Code Playgroud)

这用Iterator::by_ref.而不是使用迭代器,by_ref创建一个可变的引用.对迭代器的可变引用实现了Iterator,所以调用takecollect正常工作.但是,当这些完成后,iter仍然有效.


归档时间:

查看次数:

949 次

最近记录:

9 年,9 月 前