【问题标题】:How do I fix a missing lifetime specifier?如何修复缺少的生命周期说明符?
【发布时间】:2017-09-05 22:29:09
【问题描述】:

我有一个非常简单的方法。第一个参数接受向量分量(“A”、5、0),我将把它与另一个向量的每个元素进行比较,看看它们是否相同(_、5、_),然后打印出找到的元素的字符串。

比较 ("A", 5, 0 ) 和 ("Q", 5, 2) 应该会打印出 Q。

fn is_same_space(x: &str, y1: i32, p: i32, vector: &Vec<(&str, i32, i32)>) -> (&str) {
    let mut foundString = "";

    for i in 0..vector.len() {

        if y1 == vector[i].1 {
            foundString = vector[i].0;
        }

    }
    foundString    
}

但是,我得到了这个错误

error[E0106]: missing lifetime specifier
 --> src/main.rs:1:80
  |
1 | fn is_same_space(x: &str, y1: i32, p: i32, vector: &Vec<(&str, i32, i32)>) -> (&str) {
  |                                                                                ^ expected lifetime parameter
  |
  = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or one of `vector`'s 2 elided lifetimes

【问题讨论】:

  • 这里的重点是您返回的&amp;str 属于某人。编译器想要知道某人是谁,因此它可以知道您&amp;str 指向的内存预计会存在多长时间。您需要告诉编译器“只要传入的引用,我返回的 &amp;str 就会存在”

标签: rust lifetime


【解决方案1】:

通过指定生命周期

fn is_same_space<'a>(x: &'a str, y1: i32, p: i32, vector: &'a Vec<(&'a str, i32, i32)>) -> (&'a str)

这只是您可能对函数所做的许多可能的解释之一,因此这是一个非常保守的选择 - 它使用所有引用参数的统一生命周期。

也许您想返回一个与xvector 或与vector 中的字符串一样长的字符串;所有这些都可能有效。


强烈建议您返回并重新阅读 The Rust Programming Language。它是免费的,面向 Rust 的初学者,它涵盖了所有使 Rust 独一无二并且对程序员来说是新事物的东西。许多人在这本书上花费了很多时间,它回答了许多诸如此类的初学者问题。

具体来说,您应该阅读以下章节:

甚至还有一个second edition in the works,其章节如下:


为了好玩,我会使用迭代器重写您的代码:

fn is_same_space<'a>(y1: i32, vector: &[(&'a str, i32, i32)]) -> &'a str {
    vector.iter()
        .rev() // start from the end
        .filter(|item| item.1 == y1) // element that matches
        .map(|item| item.0) // first element of the tuple
        .next() // take the first (from the end)
        .unwrap_or("") // Use a default value
}

【讨论】:

  • 啊,谢谢您的好心先生。我知道我应该读这本书,但我更喜欢先做代码,然后再问问题。如您所见,我的类型推断是拖延。我知道这是非常糟糕的做法,应该改正我的习惯。谢谢
  • @bossrevs:我知道那种感觉;当我看到一本以语法页面开始的编程语言“书”时,我觉得我需要吐了。这很无聊,无趣,我会边走边自然捡起这些东西。新的Rust Book, 2nd edition 是不同的;这是一种亲身体验,随手附上的例子。我真的建议检查一下,至少在所有权/借用章节(第二章)之前。
【解决方案2】:

所以问题出在vector 有两个推断的生命周期,一个用于vector 本身(&amp;Vec 部分),另一个用于向量内的&amp;str。你在x 上也有一个推断的生命周期,但这真的无关紧要。

要修复它,只需指定返回的 &amp;str 与向量中的 &amp;str 一样长:

fn is_same_space<'a>(                        // Must declare the lifetime here
    x: &str,                                 // This borrow doesn't have to be related (x isn't even used)
    y1: i32,                                 // Not borrowed
    p: i32,                                  // Not borrowed or used
    vector: &'a Vec<(&'a str, i32, i32)>     // Vector and some of its data are borrowed here
) -> &'a str {                               // This tells rustc how long the return value should live
    ...
}

【讨论】:

  • &amp;Vec&lt;(&amp;'a str, i32, i32)&gt;(或者更好,&amp;[(&amp;'a str, i32, i32)],见stackoverflow.com/q/40006219/155423)应该足够了。容器的生命周期无关紧要。
  • @Shepmaster 感谢您的建议,我没想过要使用切片。我对 rust 还很陌生,并且正在努力学习。我认为我通过回答问题学到了很多 Haskell,所以我应该对 Rust 做同样的事情。看起来它已经开始工作了=)
  • 我用指向“为什么”的链接更新了该评论。出于同样的原因,我开始回答 Rust 问题,所以我明白你来自哪里!
猜你喜欢
  • 2015-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-29
  • 1970-01-01
  • 2016-02-18
  • 2011-07-29
  • 2022-07-16
相关资源
最近更新 更多