I happened upon this problem where format! creates a temporary value in a pattern that is not anchored to anything, as far as I understand it.
l
format! can't return &str because it will always allocate String. What is possible to do is to return a &str from a String, which is what you did in your code.
As the compiler hinted, the created String is immediately dropped after its creation because it went out of the current scope and one way around could be an external variable that is not bounded to the match scope. E.g.:
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);
}
If you want an [no_std] environment or don't want to do any dynamic allocation, you can take a look at this limited code snippet:
use core::str;
fn each_digit(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);
}