Как мне сделать формат! вернуть & amp; str из условного выражения?

1
задан Shepmaster 13 March 2019 в 23:59
поделиться

2 ответа

format! не может вернуть &str, потому что он всегда выделяет String. Что можно сделать, это вернуть &str из String, что вы и сделали в своем коде.

Как намекнул компилятор, созданный String сразу же удаляется после его создания, потому что он вышел из текущей области видимости, и одним из способов может быть внешняя переменная, которая не ограничена областью match. Например :

use std::fmt::Write;

fn main() {
    let mut buffer = String::with_capacity(20);
    buffer.push_str("It's a ");

    let x = 10;
    let category = match x {
        0...9 => "Between 0 and 9",
        number @ 10 => {
            write!(&mut buffer, "{}", number).unwrap();
            buffer.as_str()
        }
        _ if x < 0 => "Negative",
        _ => "Something else",
    };

    println!("{}", category);
}

Если вы хотите среду [no_std] или не хотите выполнять динамическое распределение, вы можете взглянуть на этот ограниченный фрагмент кода:

use core::str;

fn each_digit<F>(mut number: u32, mut f: F)
where
    F: FnMut(u8),
{
    while number > 0 {
        f((number % 10) as u8);
        number /= 10;
    }
}

fn main() {
    const BUFFER_LEN: usize = 20;
    let mut buffer = [0u8; BUFFER_LEN];

    let x = 12344329;
    let category = match x {
        0...9 => "Between 0 and 9",
        number @ 123443219 => {
            let mut idx = BUFFER_LEN;
            each_digit(number, |digit| {
                let ascii = digit + 48;
                idx -= 1;
                buffer[idx] = ascii;
            });
            str::from_utf8(&buffer[idx..BUFFER_LEN]).unwrap()
        },
        _ => "Something else",
    };

    assert_eq!("123443219", category);
}
0
ответ дан Caio 13 March 2019 в 23:59
поделиться

Это на 90% дубликат . Вернуть локальную строку в виде среза (& amp; str) , см. Это для множества других решений.

Есть еще одна возможность, так как все это в одной функции: вы можете объявить переменную для String и установить ее только тогда, когда вам нужно выделить. Компилятор (косвенно) предлагает следующее:

рассмотреть возможность использования привязки let для создания более долгоживущего значения

fn main() {
    let x = 42;
    let tmp;

    let category = match x {
        0...9 => "Between 0 and 9",
        number @ 10 => {
            tmp = format!("It's a {}!", number);
            &tmp
        }
        _ if x < 0 => "Negative",
        _ => "Something else",
    };

    println!("{}", category);
}

Это в основном то же самое, что и использование Cow, только что обработанный компилятором вместо определенного типа.

0
ответ дан Shepmaster 13 March 2019 в 23:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: