我implemented一个struct
,其中有一个crontab条目列表,每个条目都知道它自己的重复发生(例如crontab中的*/5 * * * *
):
extern crate chrono;
use chrono::NaiveDateTime;
pub struct Crontab<'a> {
entries: Vec<Entry<'a>>,
}
pub struct Entry<'a> {
pub recurrence: Recurrence,
pub command: &'a str,
}
pub struct Recurrence {
minutes: Vec<u8>,
hours: Vec<u8>,
days_of_month: Vec<u8>,
months: Vec<u8>,
days_of_week: Vec<u8>,
}
根据当前时间,您可以获得下一次命令:
impl Recurrence {
pub fn next_match(&self, after: NaiveDateTime) -> NaiveDateTime {
unimplemented!()
}
}
我正在尝试在Crontab
上编写一个函数来获取接下来要运行的Entry
(也就是recurrence.next_match()
最低的那个)。
impl<'a> Crontab<'a> {
fn next_run(&self, from: NaiveDateTime) -> Run<'a> {
&self.entries
.into_iter()
.map(|entry| Run {
entry: &entry,
datetime: entry.recurrence.next_match(from),
})
.min_by(|this, other| this.datetime.cmp(&other.datetime))
.unwrap()
}
}
struct Run<'a> {
entry: &'a Entry<'a>,
datetime: NaiveDateTime,
}
这会产生错误:
error[E0308]: mismatched types
--> src/main.rs:30:9
|
29 | fn next_run(&self, from: NaiveDateTime) -> Run<'a> {
| ------- expected `Run<'a>` because of return type
30 | / &self.entries
31 | | .into_iter()
32 | | .map(|entry| Run {
33 | | entry: &entry,
... |
36 | | .min_by(|this, other| this.datetime.cmp(&other.datetime))
37 | | .unwrap()
| |_____________________^ expected struct `Run`, found &Run<'_>
|
= note: expected type `Run<'a>`
found type `&Run<'_>`
类似的变种我尝试使用诸如“无法移出借来的内容”(如果将返回类型更改为&Run<'a>
)或&entry
的生存时间不够长等消息进行编译
似乎最有意义的是Run
应该引用而不是Entry
的副本,但我不确定如何兼顾生命周期和引用那一点(我不知道'a
是否指的是两个结构中相同的生命周期)。我在这里缺少什么?
答案 0 :(得分:2)
如Is there any way to return a reference to a variable created in a function?中所述,您无法在函数中创建值并返回对它的引用。没有任何东西会拥有迭代器链的结果,因此引用将指向无效数据。
这并不重要:正如评论中指出的那样,您无法在into_iter
上致电self.entries
,因为您无法从借来的内容中退出,如{ {3}}。这意味着我们不能拥有Entry
的拥有值作为迭代器链的结果。
Crontab
拥有Entry
;只要Crontab
移动,对任何Entry
的任何引用都将失效。这意味着任何引用都需要与self
生存的时间相关联;通用生命周期'a
无法发挥作用:
fn next_run(&self, from: NaiveDateTime) -> Run {
self.entries
.iter()
.map(|entry| Run {
entry,
datetime: entry.recurrence.next_match(from),
})
.min_by(|this, other| this.datetime.cmp(&other.datetime))
.unwrap()
}
或显式版本:
fn next_run<'b>(&'b self, from: NaiveDateTime) -> Run<'b> { /* ... */ }