将char转换为&str

Pri*_*six 3 string reference rust

我有一个match声明,它返回一个&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), // I want to convert this to &str
}.as_bytes()
Run Code Online (Sandbox Code Playgroud)

我试图char先将一个字符串转换为字符串,然后再将其切换为:

&(k as char).to_string()[..]
Run Code Online (Sandbox Code Playgroud)

但这给了我一生的错误:

error[E0597]: borrowed value does not live long enough
Run Code Online (Sandbox Code Playgroud)

说明这(k as char).to_string() 是一个临时值,从我能说的内容来看是有意义的,它会to_string()返回一个克隆.

我可以添加.to_string()&str上面的每个文字来产生返回值String,但这看起来既丑陋(很多重复的代码),并且可能是低效的,因为to_string()克隆了原始的字符串切片.

具体问题是我将如何char进入a &str,但更广泛的问题是有更好的解决方案,这种情况通常是做什么的.

She*_*ter 8

只要您不需要&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);
}
Run Code Online (Sandbox Code Playgroud)

如果您需要更多控制,这可以与闭包配对:

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());
}
Run Code Online (Sandbox Code Playgroud)

或者存储在一个结构中以提供一点抽象:

#[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);
    }
}
Run Code Online (Sandbox Code Playgroud)


red*_*ime 5

使用Cow很简单:

use std::borrow::Cow;

fn cow_name(v: u8) -> Cow<'static, str> {
    match v {
        0 => "KEY_0",
        1 => "KEY_1",
        _ => return (v as char).to_string().into(),
    }.into()
}
Run Code Online (Sandbox Code Playgroud)

鉴于这k是一个u8(否则您的代码将无法编译),您也可以使用常量数组:

const NAMES: [&'static str; 256] = [
    "KEY_0", "KEY_1", //  ...
    " ", "!", "\"", "#", // ...
];

fn const_name(k: u8) -> &'static str {
    NAMES[k as usize]
}
Run Code Online (Sandbox Code Playgroud)

操场