为什么我不能从一个函数返回Vec<&str>?

5

我试图返回一个Vec<&str>,但在while循环内部将 u64 转换为 &str 时遇到了问题:

fn latest_ids<'a>(current_id: u64, latest_id: u64) -> Vec<&'a str> {
    let mut ids: Vec<&str> = vec![];
    let mut start = current_id;
    while !(start >= latest_id) {
        start += 1;
        ids.push(start.to_string().as_str());
    }
    ids
}

无法返回指向临时值的引用。
如果我只返回一个Vec,那么它可以正常工作。
fn latest_ids<'a>(current_id: u64, latest_id: u64) -> Vec<String> {
    let mut ids: Vec<String> = vec![];
    let mut start = current_id;
    while !(start >= latest_id) {
        start += 1;
        ids.push(start.to_string());
    }
    ids
}

在此之后调用的下一个函数需要一个&str类型的参数,那我是应该返回一个Vec<&str>还是只返回一个Vec<String>让调用者处理转换?

获取latest_ids()结果后要调用的下一个函数:

pub fn add_queue(job: &Job, ids: Vec<&str>) -> Result<(), QueueError> {
    let meta_handler = MetaService {};

    match job.meta_type {
        MetaType::One => meta_handler.one().add_fetch_queue(ids).execute(),
        MetaType::Two => meta_handler.two().add_fetch_queue(ids).execute(),
        MetaType::Three => meta_handler.three().add_fetch_queue(ids).execute(),
    }
}
1个回答

2
你所介绍的生命周期是指“我正在返回一个字符串引用的向量,其生命周期超过了这个函数”。这并不正确,因为你创建了一个String,然后存储了对它的引用。该引用将在创建String的范围结束时失效。
从纯“设计”角度回答你的问题:
“我应该返回Vec<&str>还是只返回String类型的Vec并让调用者处理转换?”
该方法被称为latest_ids,你传递的ID是64位整数。考虑到方法名称,我认为应该返回64位整数,由调用者进行转换。
fn main() -> std::io::Result<()> {

    let ids: Vec<String> = latest_ids(5, 10).iter().map(|n| n.to_string()).collect();
    let ids_as_string_references: Vec<&str> = ids.iter().map(|n| &**n).collect();

    println!("{:?}", ids_as_string_references);

    Ok(())
}

fn latest_ids(current_id: u64, latest_id: u64) -> Vec<u64> {
    let mut ids = vec![];
    let mut start = current_id;
    while !(start >= latest_id) {
        start += 1;
        ids.push(start);
    }
    ids
}

打印: ["6", "7", "8", "9", "10"]

这里双重处理是因为您要求引用。根据代码周围的进一步上下文,可能不需要双重处理。如果您在问题中更新有关需要&str引用向量的下一个函数的更多信息,我可以更新我的答案以帮助重新设计它。

最初的回答是因为您要求引用。根据代码周围的进一步上下文,可能不需要双重处理。如果您在问题中更新有关需要&str引用向量的下一个函数的更多信息,我可以更新我的答案以帮助重新设计它。


感谢您详细的回复。我已经更新了问题,并调用了下一个方法。 - James
这些整数ID会传递多深?最好的方式可能是一直传递整数向量,直到迭代该向量 - 然后根据循环需要将其转换为&str - Simon Whitehead
它不再下降到任何更深的级别。我认为add_queue应该进行转换,因为其他函数使用meta_handler.one().add_fetch_queue(ids).execute(),其中原始ids是字母数字混合的。你觉得呢? - James
说实话,如果没有整体看到它,很难给出建议。尽管如此,我的建议就是尽可能将双重处理/转换放在调用堆栈的最底层。如果您认为在add_queue内部进行处理是合适的,那么这听起来不错。 - Simon Whitehead

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接