简体   繁体   English

如何使用 structs 和 impl 的生命周期来推断实现的适当生命周期?

[英]How to infer an appropriate lifetime for an implementation using lifetimes for structs and impl?

How do I resolve this error?如何解决此错误? What exactly am I telling the compiler when I use the "anonymous lifetime" in impl ?当我在impl中使用“匿名生命周期”时,我到底在告诉编译器什么?

struct LineHandlerInfo<'a> {
    label: &'a str,
    match_literal: &'a str,
    f: fn(&str) -> Option<&str>,
}

struct Game<'a> {
    handlers: Vec<LineHandlerInfo<'a>>,
}

impl Game<'_> {
    fn match_str<'a>(
        &'a mut self,
        label: &'a str,
        match_literal: &'a str,
        mut f: fn(&str) -> Option<&str>,
    ) {
        let mut lh = LineHandlerInfo {
            label,
            match_literal,
            f,
        };
        self.handlers.push(lh);
    }
}

fn main() {
    let mut g = Game {
        handlers: Vec::new(),
    };
    g.match_str("echo hello", "hello", |s| {
        println!("{}", s);
        None
    });
}

When I attempt to compile, I get the following error:当我尝试编译时,出现以下错误:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
  --> src/main.rs:18:22
   |
18 |         let mut lh = LineHandlerInfo {
   |                      ^^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the lifetime 'a as defined on the method body at 12:18...
  --> src/main.rs:12:18
   |
12 |     fn match_str<'a>(
   |                  ^^
note: ...so that reference does not outlive borrowed content
  --> src/main.rs:19:13
   |
19 |             label,
   |             ^^^^^
note: but, the lifetime must be valid for the lifetime '_ as defined on the impl at 11:11...
  --> src/main.rs:11:11
   |
11 | impl Game<'_> {
   |           ^^
   = note: ...so that the expression is assignable:
           expected LineHandlerInfo<'_>
              found LineHandlerInfo<'_>

How do I resolve this error and what exactly am I telling the compiler when I specify a lifetime on impl Game when I already have a lifetime on the struct?我该如何解决这个错误,当我在impl Game上指定一个生命周期时,当我在结构上已经有一个生命周期时,我到底告诉编译器什么?

How do I resolve this error and what exactly am I telling the compiler when I specify a lifetime on impl Game when I already have a lifetime on the struct?我该如何解决这个错误,当我在 impl Game 上指定一个生命周期时,当我在结构上已经有一个生命周期时,我到底告诉编译器什么?

I suspect your confusion stems from an incomplete understanding of the way in which lifetimes are declared and used in Rust.我怀疑您的困惑源于对 Rust 中声明和使用生命周期的方式的不完全理解。

Struct Lifetimes结构生命周期

In order to use a lifetime on a struct, you declare the lifetime inside the <> adjacent to the name of the struct you are declaring, and then refer to that lifetime inside the struct definition.为了在结构上使用生命周期,您在<>声明与您正在声明的结构名称相邻的生命周期,然后在结构定义中引用该生命周期。 Importantly, note that the lifetime declared there is scoped to the struct definition - it has no meaning outside.重要的是,请注意,在那里声明的生命周期仅限于结构定义 - 它在外部没有任何意义。

For example (using the MRE that @Shepmaster provided):例如(使用@Shepmaster 提供的 MRE):

struct Game<'a> {
    handlers: Vec<&'a str>,
}

The struct Game contains a vector of references to strings, and the strings which are referenced must last at least as long as the Game struct.结构体Game包含一个对字符串的引用向量,并且被引用的字符串必须至少与Game结构体一样长。

Impl Lifetimes实现生命周期

When using a lifetime specifier on an impl block, you declare the lifetime inside the <> adjacent to the impl keyword, after which you may refer to the lifetime both in the struct being implemented, and inside the implementation itself, like this:在 impl 块上使用生命周期说明符时,您在 impl 关键字旁边的<>声明生命周期,之后您可以在正在实现的结构和实现本身中引用生命周期,如下所示:

impl<'b> Game<'b> {
    fn match_str(&mut self, label: &'b str) {
        self.handlers.push(label);
    }
}

Note that I am using an entirely different lifetime name here ( 'b ) to illustrate that the the lifetime declaration on the struct is independent of the one on the impl block.请注意,我在这里使用了一个完全不同的生命周期名称( 'b )来说明结构上的生命周期声明独立于 impl 块上的声明。

Breaking this down:打破这个:

impl<'b>

This means that we are defining an implementation for a struct, and within that definition we will use the lifetime 'b这意味着我们正在为结构定义一个实现,并且在该定义中我们将使用生命周期'b

 Game<'b> {

This means that the impl is for the struct Game with lifetime 'b - so any references to self inside this implementation are going to automatically have lifetime 'b as well.这意味着 impl 用于具有生命周期'b的结构Game - 因此在此实现中对self的任何引用也将自动具有生命周期'b

fn match_str(&mut self, label: &'b str) {

Here we define the method match_str which takes an argument label .这里我们定义了label match_str label is a string slice which also has the lifetime 'b - so it must last at least as long as the self that the method is called on. label是一个字符串切片,它也有生命周期'b - 所以它必须至少与调用该方法的self一样长。

In your original code, you had something like this:在您的原始代码中,您有以下内容:

impl Game<'_> {
    fn match_str<'a>(&mut self, label: &'a str) {
    ...
    }
}

This was telling the compiler:这告诉编译器:

  • That you are starting a new impl block that, and there are no lifetimes declared at impl level您正在启动一个新的 impl 块,并且没有在 impl 级别声明的生命周期
  • That the implementation is for the struct Game ;该实现是针对 struct Game的; this struct has a lifetime parameter but we don't care about it and we are not going to tie it to any element of the implementation这个结构有一个生命周期参数,但我们不关心它,我们不会将它绑定到实现的任何元素
  • We are defining a method match_str , and we are declaring a lifetime 'a which we can refer to in the rest of the function signature我们正在定义一个方法match_str ,并且我们正在声明一个生命周期'a ,我们可以在 function 签名的 rest 中引用它
  • We have an argument label which has the lifetime a , but we aren't relating this lifetime to anything else我们有一个参数label的生命周期a ,但我们没有将此生命周期与其他任何东西联系起来

More information:更多信息:

How do I resolve this error?如何解决此错误?

Remove the generic lifetime from the function, provide a name for the lifetime on the impl block instead of using the anonymous lifetime, then use the named lifetime in the function arguments.从 function 中删除通用生命周期,在impl块上为生命周期提供名称而不是使用匿名生命周期,然后在 function arguments 中使用命名生命周期。 Remove the lifetime from &self :&self中删除生命周期:

impl<'a> Game<'a> {
    fn match_str(&mut self, label: &'a str, match_literal: &'a str, f: fn(&str) -> Option<&str>) {
        self.handlers.push(LineHandlerInfo {
            label,
            match_literal,
            f,
        });
    }
}

See also:也可以看看:

What exactly am I doing when I use the "anonymous lifetime" in impl?当我在 impl 中使用“匿名生命周期”时,我到底在做什么?

You are effectively stating "I know there's a lifetime here, but I don't care about it".您实际上是在说“我知道这里有一生,但我不在乎”。 However, that's not true for your case;但是,您的情况并非如此。 you do care about the lifetime that parameterizes the type because that's what your variables need to match.您确实关心参数化类型的生命周期,因为这是您的变量需要匹配的。

See also:也可以看看:

for a struct with a function pointer in it对于其中带有 function 指针的结构

This has nothing to do with function pointers.这与 function 指针无关。 When encountering problems while programing, I recommend creating a minimal, reproducible example , stripping out things that don't make the error go away.在编程时遇到问题时,我建议创建一个最小的、可重现的示例,去掉不会导致错误 go 消失的东西。 This allows you to focus on exactly the problem at hand.这使您可以准确地专注于手头的问题。 For example, this reproduces the same error:例如,这会重现相同的错误:

struct Game<'a> {
    handlers: Vec<&'a str>,
}

impl Game<'_> {
    fn match_str<'a>(&mut self, label: &'a str) {
        self.handlers.push(label);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法推断出合适的生命周期 - cannot infer an appropriate lifetime for lifetime 返回具有相同生命周期的结构的迭代器的方法的生命周期 - Lifetimes for method returning iterator of structs with same lifetime 如何修复:无法推断自动强制的适当生命周期 - How to fix: cannot infer an appropriate lifetime for automatic coercion 我怎样才能让 impl Trait 使用适当的生命周期来对具有另一个生命周期的值进行可变引用? - How can I get impl Trait to use the appropriate lifetime for a mutable reference to a value with another lifetime in it? 从Iterator实现调用方法时,无法推断autoref的适当生命周期 - Cannot infer appropriate lifetime for autoref when calling a method from an Iterator implementation 在结构中存储闭包 - 无法推断出适当的寿命 - Storing a closure in a structure — cannot infer an appropriate lifetime 无法为返回引用的闭包推断合适的生命周期 - Cannot infer an appropriate lifetime for a closure that returns a reference 由于需求冲突,无法推断出合适的生命周期 - Cannot infer an appropriate lifetime due to conflicting requirements 推断包括内部参照在内的方法的适当寿命 - Infer an appropriate lifetime for methods including interior references 调用 lambda 时“无法推断出适当的生命周期” - “Cannot infer an appropriate lifetime” when calling lambda
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM