How do you do a string slice in a const function?
const fn cya_first_char(inc: &str) -> &str {
&inc[1..]
// ~~~~~ Error: cannot call non-const operator in constant functions
}
On
There is not a lot of const fn in &str for now. If you want you can use array and from_utf8() that is const and test how robust is rustc using some recursive:
// cause brute force is sometime more simple
const fn cya_first_char_aux(inc: &[u8]) -> &str {
match inc {
[_, rest @ ..] => match std::str::from_utf8(rest) {
Ok(s) => s,
_ => cya_first_char_aux(rest),
},
_ => "",
}
}
const fn cya_first_char(inc: &str) -> &str {
cya_first_char_aux(inc.as_bytes())
}
fn main() {
println!("{}", cya_first_char("Hello world!"));
println!("{}", cya_first_char("老虎 Léopard"));
println!("{}", cya_first_char(""));
}
strdoesn't have too many const methods, butas_bytesis, and[u8]has a constsplit_atmethod. Then you can turn that back intostrwithstd::str::from_utf8.This will scan the entire rest of the string for validity every time, so it will detrimentally affect performance if called on long strings or when called many times. If that's what you need, then it'll probably be worth reimplementing
is_char_boundaryin const and using that withfrom_utf8_unchecked.Here is one that takes the first character instead of the first byte.
This one gets around the performance issue by only checking the first character for validity, and assuming the rest. This way, it only has to check at most 1 + 2 + 3 + 4 = 10 bytes for any length of string.
This is still not ideal, but will run in constant time.