Функция, возвращающая Vec <& str> - PullRequest
1 голос
/ 01 мая 2019

Я пытаюсь вернуть вектор & str, но у меня возникают проблемы при попытке преобразовать u64 в & str внутри цикла while.

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
}

не может вернуть значение, ссылающееся на временное значение

Если я верну только вектор строк, он будет работать нормально.

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 голосов
/ 01 мая 2019

Введенное вами время жизни говорит: «Я возвращаю вектор строковых ссылок, чье время жизни превышает эту функцию». Это неправда, потому что вы создаете String, а затем сохраняете ссылку на него. Эта ссылка умрет в конце области, в которой создается String.

Чтобы ответить на ваш вопрос чисто из "дизайна" POV:

Должен ли я возвращать Vec <& str> или просто возвращать Vec типа String и позволить вызывающей стороне обработать преобразование?

Метод называется latest_ids .. и идентификаторы, которые вы передаете, являются 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 ссылок, я могу обновить свой ответ, чтобы помочь изменить его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...