我有一个返回 &str
的 match
语句:
match k {
SP_KEY_1 => "KEY_1",
SP_KEY_2 => "KEY_2",
SP_KEY_3 => "KEY_3",
SP_KEY_4 => "KEY_4",
SP_KEY_5 => "KEY_5",
SP_KEY_6 => "KEY_6",
_ => (k as char), // I want to convert this to &str
}.as_bytes()
我尝试先将 char
转换为字符串,然后从中提取一部分:
&(k as char).to_string()[..]
但这给了我终生错误:
error[E0597]: borrowed value does not live long enough
声明 (k as char).to_string()
是一个临时值,据我所知,这是有道理的 to_string()
返回一个克隆。
我可以将 .to_string()
添加到上面的每个 &str
文字中,使返回值成为 String
,但这看起来既丑陋(a很多重复的代码),并且可能效率低下,因为 to_string()
克隆原始字符串切片。
具体的问题是如何将 char
变成 &str
,但更广泛的问题是是否有更好的解决方案,这种情况通常是怎么做的。
最佳答案
只要您不需要从函数返回&str
,就可以使用char::encode_utf8
完全避免堆分配。 :
const SP_KEY_1: u8 = 0;
const SP_KEY_2: u8 = 1;
const SP_KEY_3: u8 = 2;
const SP_KEY_4: u8 = 3;
const SP_KEY_5: u8 = 4;
const SP_KEY_6: u8 = 5;
fn main() {
let k = 42u8;
let mut tmp = [0; 4];
let s = match k {
SP_KEY_1 => "KEY_1",
SP_KEY_2 => "KEY_2",
SP_KEY_3 => "KEY_3",
SP_KEY_4 => "KEY_4",
SP_KEY_5 => "KEY_5",
SP_KEY_6 => "KEY_6",
_ => (k as char).encode_utf8(&mut tmp),
};
println!("{}", s);
}
如果您需要更多控制,这可以与闭包配对:
fn adapt<F, B>(k: u8, f: F) -> B
where
for<'a> F: FnOnce(&'a str) -> B,
{
let mut tmp = [0; 4];
let s = match k {
SP_KEY_1 => "KEY_1",
SP_KEY_2 => "KEY_2",
SP_KEY_3 => "KEY_3",
SP_KEY_4 => "KEY_4",
SP_KEY_5 => "KEY_5",
SP_KEY_6 => "KEY_6",
_ => (k as char).encode_utf8(&mut tmp),
};
f(s)
}
fn main() {
adapt(0, |s| println!("{}", s));
let owned = adapt(0, |s| s.to_owned());
}
或者存储在结构中以提供一点抽象:
#[derive(Debug, Default)]
struct Foo {
tmp: [u8; 4],
}
impl Foo {
fn adapt(&mut self, k: u8) -> &str {
match k {
SP_KEY_1 => "KEY_1",
SP_KEY_2 => "KEY_2",
SP_KEY_3 => "KEY_3",
SP_KEY_4 => "KEY_4",
SP_KEY_5 => "KEY_5",
SP_KEY_6 => "KEY_6",
_ => (k as char).encode_utf8(&mut self.tmp),
}
}
}
fn main() {
let mut foo = Foo::default();
{
let s = foo.adapt(0);
}
{
let s = foo.adapt(42);
}
}
关于string - 将 char 转换为 &str,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47629596/