如何在Fn特征绑定返回的引用上定义生存期? [英] How to define lifetimes on a Fn trait bound returning references?

查看:60
本文介绍了如何在Fn特征绑定返回的引用上定义生存期?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个具有字段的结构,该字段在F上通用,其中F实现类似Fn(&mut Compiler, &[Token]) -> &Token的内容.唯一的问题是,我不确定如何在Fn特征上定义生存期,该生存期是否满足返回的&Token引用作为参数提供的&[Token]切片中的数据的约束.到目前为止,我尝试过的所有操作都引发了神秘的错误.

I'm trying to create a struct with a field, generic over F where F implements something like: Fn(&mut Compiler, &[Token]) -> &Token. The only issue is, I'm not sure how I define lifetimes on the Fn trait which satisfy the constraint that the returned &Token references data in the &[Token] slice supplied as an argument. Everything I've tried has thrown cryptic errors thus far.

这是一个MVCE,它演示了代码(没有生命周期):

Here is an MVCE which demonstrates the code (without any lifetimes):

struct Compiler;
#[derive(Debug)]
struct Token(usize);

impl Compiler {
    // missing lifetime paramters here
    fn meth(&mut self, tokens: &[Token]) -> &Token {
        tokens.get(0).unwrap()
    }
}

// missing lifetime paramters here    
struct Rule<F> where F: Fn(&mut Compiler, &[Token]) -> &Token {
    func: F
}

fn main() {
    let mut c = Compiler;
    let tokens = vec![Token(0), Token(1), Token(2)];
    let r = Rule { func: Compiler::meth };
    (r.func)(&mut c, &tokens);
}

自然,它无法编译并显示错误:

Naturally this fails to compile with the error:

   Compiling playground v0.0.1 (/playground)
error[E0106]: missing lifetime specifier
  --> src/main.rs:11:56
   |
11 | struct Rule<F> where F: Fn(&mut Compiler, &[Token]) -> &Token {
   |                                                        ^ expected lifetime parameter
   |
   = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2

我试图到处添加生命周期说明符,四处移动,但似乎无济于事.我真的很感谢对此问题的任何见解.谢谢!

I've attempted to add lifetimes specifiers here and there, moving things around but nothing seems to work. I would really appreciate any insight into the issue. Thanks!

推荐答案

根据@Stargateur的评论,解决方案是添加

As per @Stargateur's comment, the solution was to add a Higher-Ranked Trait Bound to the Fn trait declaration. The where for clause is a piece of syntax completely specific to this use case.

正常的生命周期界限不起作用,因为我们不知道在调用时间之前将什么生命周期应用于函数的参数.

Normal lifetime bounds don't work, because we don't know what lifetimes will be applied to the function's arguments until call time.

所以我们从这里开始:

struct Rule<F> where F: Fn(&mut Compiler, &[Token]) -> &Token {
    func: F
}

对此:

struct Rule<F> where for<'a> F: Fn(&mut Compiler, &'a[Token]) -> &'a Token {
    func: F
}

其中规定,应用于函数F的特征范围必须满足在调用时'a 的所有潜在生存期.魔术!

Which dictates that the trait bounds applied to function F must satisfy all potential lifetimes of 'a at call time. Magic!

这篇关于如何在Fn特征绑定返回的引用上定义生存期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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