gpt4 book ai didi

rust - 如何在 Rust 中返回引用 self 的结构?

转载 作者:行者123 更新时间:2023-11-29 08:14:03 25 4
gpt4 key购买 nike

我已经 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 是否在两个结构中指代相同的生命周期)。我在这里缺少什么?

最佳答案

Is there any way to return a reference to a variable created in a function? 中所述,您不能在函数中创建值并返回对它的引用。没有任何东西会拥有您的迭代器链的结果,因此引用将指向无效数据。

这甚至都不重要:正如评论中指出的那样,您不能在 self.entries 上调用 into_iter,因为您无法从借用的内容中移出以开始与,如 Cannot move out of borrowed content 中所述.这意味着我们不能将 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> { /* ... */ }

关于rust - 如何在 Rust 中返回引用 self 的结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49245465/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com