出现“缺少生命周期说明符"错误 [英] Getting 'Missing Lifetime specifier' error

查看:90
本文介绍了出现“缺少生命周期说明符"错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码:

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(),
    }
  }
}

在引用&Query<T>的地方,我不断收到缺少生命周期说明符".如何解决此错误?

I keep getting 'missing lifetime specifier' where I am referencing &Query<T>. How do I fix this error?

推荐答案

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

First, note that &T/&mut T and *const T/*mut T are different types of pointers in Rust. The former are called "references" and they are statically checked in various ways (including borrowing analysis) and they can't be null or point to some invalid object. The latter are called "raw pointers" and are used primarily in abstractions implementations and for FFI.

因此,写作

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

prevnext属于&Whatever类型时不正确-ptr::null()返回的*const Whatever类型值与(<安全)与&Whatever不兼容.

when prev and next are of type &Whatever is incorrect - ptr::null() returns values of type *const Whatever which is not compatible (safely) with &Whatever.

Rust中的引用始终具有一定的生存期-编译器使用它来检查引用是否始终指向有效的数据.此生存期在引用类型:&'a T中指定.在大多数情况下,编译器可以自动推断正确的生存期,因此您几乎不需要在局部变量类型甚至函数声明中编写它们:

References in Rust always have some lifetime associated with them - it is used by the compiler to check that references always point to valid pieces of data. This lifetime is specified in reference type: &'a T. In most cases the compiler can infer correct lifetimes automatically, so you seldom need to write them in types of local variables or even in function declarations:

let x: &str = "hello";

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

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

However, when you want to put references to a structure, there is just no way the compiler can infer the lifetime in the structure declaration (because it can be arbitrary and depends on the way the structure values are used), and so you need to specify lifetime parameters explicitly:

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

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

In this particular case, though, it seems that you want to implement some kind of doubly linked structure. Unfortunately, Rust references can't be used for this. Lifetime requirements prohibit creation of loops via references - you just can't store a reference to x in y if x has a reference to y inside it. The only way such structure can be constructed is through mutation:

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

但是您不能对具有指向它的引用的对象进行突变,即,上面的代码无效.

But you can't mutate an object which has a reference pointing to it, that is, the above code is invalid.

您想要实现的目标通常称为 RFC问题,我们可能会看到一些进展他们将来.

The thing you're trying to achieve is usually called intrusive data structures, and for now they are not well supported in Rust. There is an RFC issue on that, and we may probably see some progress on them in future.

您可以在此处执行几项操作,最简单的操作可能是重构代码,而无需使用双向链接结构.几乎总是可以将数据放在Vec之类的连续数组中,并使用索引来访问它,而且由于缓存的局部性,即使对于简单遍历,它也更有可能效率更高.

There are several things you can do here, the most easiest one probably would be to refactor your code in such a way that you won't need to use a doubly-linked structure. Almost always you can put your data in a contiguous array like Vec and use indices to access it, and most likely it would be more efficient even for simple traversal because of cache locality.

另一种选择是使用非侵入式链表,例如可用的在标准库中.

Another option would be to use a non-intrusive linked list, like the one which is available in the standard library.

当然,您总是可以使用原始指针.在需要它们时使用它们没有什么错,并且大多数标准库抽象(例如上面的链接列表)都在内部以某种方式使用它们.但是,就您而言,它们应该是万不得已的方法-最有可能在没有它们的情况下有多种方法可以满足您的需求.

And, of course, you can always drop to using raw pointers. There is nothing wrong in using them when they are required, and most of the standard library abstractions (like the linked list above) are using them in some way internally. In your case, however, they should be the last resort - most likely there are ways to do what you want without them.

这篇关于出现“缺少生命周期说明符"错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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