如何声明闭包参数的生存期? [英] How to declare a lifetime for a closure argument?

查看:46
本文介绍了如何声明闭包参数的生存期?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为Rust中的闭包声明生存期,但是我找不到添加生存期声明的方法.

I would like to declare a lifetime for a closure in Rust, but I can't find a way to add a lifetime declaration.

use std::str::SplitWhitespace;

pub struct ParserError {
    pub message: String,
}

fn missing_token(line_no: usize) -> ParserError {
    ParserError {
        message: format!("Missing token on line {}", line_no),
    }
}

fn process_string(line: &str, line_number: usize) -> Result<(), ParserError> {
    let mut tokens = line.split_whitespace();

    match try!(tokens.next().ok_or(missing_token(line_number))) {
        "hi" => println!("hi"),
        _ => println!("Something else"),
    }

    // The following code gives "cannot infer appropriate lifetime.....
    // let nt = |t: &mut SplitWhitespace| t.next().ok_or(missing_token(line_number));
    // match try!(nt(&mut tokens)) {
    //     "there" => println!("there"),
    //     _ => println!("_"),
    // }

    // Where should I declare the lifetime 'a?
    // let nt = |t: &'a mut SplitWhitespace| t.next().ok_or(missing_token(line_number));
    // match try!(nt(&mut tokens)) {
    //     "there" => println!("there"),
    //     _ => println!("_"),
    // }

    return Ok(());
}

fn main() {
    process_string("Hi there", 5).ok().expect("Error!!!");
    process_string("", 5).ok().expect("Error!!! 2");
}

在操场上完成示例代码.

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
  --> src/main.rs:22:42
   |
22 |     let nt = |t: &mut SplitWhitespace| t.next().ok_or(missing_token(line_number));
   |                                          ^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 22:14...
  --> src/main.rs:22:14
   |
22 |     let nt = |t: &mut SplitWhitespace| t.next().ok_or(missing_token(line_number));
   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   = note: ...so that the types are compatible:
           expected std::iter::Iterator
              found std::iter::Iterator
note: but, the lifetime must be valid for the call at 23:16...
  --> src/main.rs:23:16
   |
23 |     match try!(nt(&mut tokens)) {
   |                ^^^^^^^^^^^^^^^
note: ...so type `std::result::Result<&str, ParserError>` of expression is valid during the expression
  --> src/main.rs:23:16
   |
23 |     match try!(nt(&mut tokens)) {
   |                ^^^^^^^^^^^^^^^

如何为该关闭声明生存期'a?

How can I declare the lifetime 'a for this closure?

推荐答案

&mut SplitWhitespace实际上是&'b mut SplitWhitespace<'a>.此处的相关生存期为'a,因为它指定了next返回的字符串片段的生存期.由于在line参数上应用了split_whitespace函数,因此需要将'a设置为与line参数相同的生存期.

The &mut SplitWhitespace is actually a &'b mut SplitWhitespace<'a>. The relevant lifetime here is the 'a, as it specifies how long the string slices that next returns live. Since you applied the split_whitespace function on your line argument, you need to set 'a to the same lifetime that the line argument has.

因此,第一步是将生存期添加到line:

So as a first step you add a lifetime to line:

fn process_string<'a>(line: &'a str, line_number: usize) -> Result<(), ParserError> {

,然后将生存期添加到闭包中的类型中:

and then you add the lifetime to the type in your closure:

let nt = |t: &mut SplitWhitespace<'a>| t.next().ok_or(missing_token(line_number));

请注意,虽然这可以回答您的问题,但正确的解决方案是 @AB的解决方案.

Note that while this answers your question, the correct solution to your Problem is @A.B.'s solution.

这篇关于如何声明闭包参数的生存期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆