string - 将 char 转换为 &str

标签 string reference rust

我有一个返回 &strmatch 语句:

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/

相关文章:

.net - .NET程序集引用对我来说是一个循环

c++ - 你会推荐这种复制字符串的方法吗?

multithreading - 是否可以仅使用 std 访问具有多个线程的不相交切片?

rust - 当包含在 include_bytes 宏中的文件被更改时,我如何告诉 Cargo 重建?

rust - 如何解决 RefCell 问题?

java - 将字符串添加到另一个类的数组列表中

java - 如何在java中翻转句子中的两个单词

c# - 如何避免对 UserControl 的引用进行硬编码?

ios - 如何从 Swift 2 中的字符串中删除特殊字符?

c - 使用 C 程序从已识别的文本中仅搜索四个词