如何在Fn特征绑定返回的引用上定义生存期? [英] How to define lifetimes on a Fn trait bound returning references?
问题描述
我正在尝试创建一个具有字段的结构,该字段在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!
推荐答案
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屋!