【问题标题】:Getting 'Missing Lifetime specifier' error出现“缺少生命周期说明符”错误
【发布时间】:2015-08-24 01:08:23
【问题描述】:

这是我的代码:

use std::ptr;

struct Query<T>{
  data: T,
  prev: & Query<T>,
  next: & Query<T>,
}
impl<T> Query<T>{
  fn new(name: T) -> Query<T>{
    Query{
      data: name,
      prev: ptr::null(),
      next: ptr::null(),
    }
  }
}

我在引用 &amp;Query&lt;T&gt; 的地方不断收到“缺少生命周期说明符”。如何解决此错误?

【问题讨论】:

  • 我推荐阅读 Rust 书:doc.rust-lang.org/book/lifetimes.html。您还混淆了借用指针和原始指针,这不会让您有任何帮助。最后,您似乎正在尝试创建一个双向链表,这在学习该语言的基本语义之前应该尝试:Rust 对此非常无情。
  • 我正在阅读这本书,目前正在参考下一个和上一个查询对象。不过,我似乎需要指针来执行此操作,否则它将访问“无限”查询,正如我认为的书中所说的那样。

标签: compiler-errors rust lifetime


【解决方案1】:

首先,请注意 &amp;T/&amp;mut T*const T/*mut T 在 Rust 中是不同类型的指针。前者称为“引用”,以各种方式(包括借用分析)进行静态检查,不能为空或指向某个无效对象。后者称为“原始指针”,主要用于抽象实现和 FFI。

因此,写作

Query {
    data: name,
    prev: ptr::null(),
    next: ptr::null(),
}

prevnext 的类型为 &amp;Whatever 时不正确 - ptr::null() 返回与 &amp;Whatever 不兼容(安全)的 *const Whatever 类型的值。

Rust 中的引用总是有一些与之相关的生命周期——编译器使用它来检查引用是否总是指向有效的数据片段。此生命周期在引用类型中指定:&amp;'a T。在大多数情况下,编译器可以自动推断出正确的生命周期,因此您很少需要将它们写入局部变量类型甚至函数声明中:

let x: &str = "hello";

fn print_str(s: &str) { println!("{}", s); }

但是,当您想要对结构进行引用时,编译器无法在结构声明中推断生命周期(因为它可以是任意的,并且取决于结构值的方式 被使用),因此您需要明确指定生命周期参数:

struct Query<'a, T> {
    data: T,
    prev: &'a Query<'a, T>,
    next: &'a Query<'a, T>,
}

不过,在这种特殊情况下,您似乎想要实现某种双向链接结构。不幸的是,Rust 引用不能用于此。生命周期要求禁止通过引用创建循环 - 如果 x 内部有对 y 的引用,您就不能在 y 中存储对 x 的引用。构建这种结构的唯一方法是通过突变:

let mut x = SomeStructure(None);
let y = SomeStructure(Some(&x));
x.0 = Some(&y);

但是你不能改变一个有引用指向它的对象,也就是说上面的代码是无效的。

你想要实现的东西通常称为intrusive data structures,目前它们在 Rust 中没有得到很好的支持。上面有一个RFC issue,将来我们可能会看到它们的一些进展。

您可以在这里做几件事情,最简单的一件可能是重构您的代码,这样您就不需要使用双链接结构了。您几乎总是可以将数据放在一个连续的数组中,例如 Vec 并使用索引来访问它,而且由于缓存的局部性,即使是简单的遍历也很可能会更有效。

另一种选择是使用非侵入式链表,例如 in the standard library 提供的链表。

当然,您也可以随时使用原始指针。在需要时使用它们并没有错,并且大多数标准库抽象(如上面的链表)都在内部以某种方式使用它们。但是,在您的情况下,它们应该是最后的手段 - 很可能有一些方法可以在没有它们的情况下做您想做的事情。

【讨论】:

  • 是的,我试图使用这种方法从头开始创建一种数据库形式,但目前显然不可能。我会想办法做到的。
猜你喜欢
  • 2017-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-29
  • 1970-01-01
  • 1970-01-01
  • 2016-02-18
相关资源
最近更新 更多