,rust,lifetime"/>

首页 > 解决方案 > 如何将 &str 生命周期传递给 Box

问题描述

我正在尝试做简单的电报机器人。对于提供的问题,我必须回答一些问题。

问题是我不能使用借用的问题(字符串)部分将其传递给数据库保存功能。

我已经尽可能地削减了我的代码:

pub enum Answer {
    DbCommand(Box<dyn Fn()>),
}

pub fn process(question: &str) -> Answer {
    let parts: Vec<&str> = question
        .split(" ")
        .collect();

    let channel = parts.get(1).unwrap();

    Answer::DbCommand(Box::new(|| {
        save_to_db(channel)
    }))
}

pub fn save_to_db(chan: &str) {
    // Saving to db
}

操场

输出是:

error[E0621]: explicit lifetime required in the type of `question`
  --> src/lib.rs:12:23
   |
5  |   pub fn process(question: &str) -> Answer {
   |                            ---- help: add explicit lifetime `'static` to the type of `question`: `&'static str`
...
12 |       Answer::DbCommand(Box::new(|| {
   |  _______________________^
13 | |         save_to_db(channel)
14 | |     }))
   | |______^ lifetime `'static` required

如果我添加一些函数生命周期,那么我会收到错误 E0495。没有太多关于它的信息

标签: rustlifetime

解决方案


split不分配任何东西,它只迭代初始字符串,保持对它的引用。您需要拥有该字符串并将其移动到闭包中:

pub enum Answer {
    DbCommand(Box<dyn Fn()>),
}

pub fn process(question: &str) -> Answer {
    let channel = question.split(" ").nth(1).unwrap().to_owned();

    Answer::DbCommand(Box::new(move || save_to_db(&channel)))
}

pub fn save_to_db(chan: &str) {
    // Saving to db
}

顺便说一句,在这种情况下你不需要收集任何东西。

如果你真的不想分配一个字符串,你可以让你的结构在整个生命周期中都是通用的,但我认为这会增加不必要的复杂性。:

pub enum Answer<'a> {
    DbCommand(Box<dyn Fn() + 'a>),
}

pub fn process(question: &str) -> Answer {
    let channel = question.split(" ").nth(1).unwrap();

    Answer::DbCommand(Box::new(move || save_to_db(channel)))
}

pub fn save_to_db(chan: &str) {
    // Saving to db
}

这是因为 trait 对象默认具有隐式'static生命周期。


推荐阅读