Rust无标准库环境下如何实现char类型与&str类型的拼接
no_std 环境下 Rust 拼接 char 与 &str 的实现方案
以下两种方案分别适配有无堆分配的内核/嵌入式场景:
方案1:固定栈缓冲区实现(无需堆分配,推荐嵌入式shell使用)
该方案不需要额外依赖,也不需要你实现内核堆分配器,仅通过栈上数组即可完成拼接,性能最高且无内存碎片风险:
/// 拼接char和&str,将结果写入传入的缓冲区,返回拼接后的&str /// 参数buf:栈上分配的u8数组,长度需要大于等于 4(char最大UTF-8长度) + 待拼接&str的长度 fn concat_char_and_str<'a>(ch: char, s: &str, buf: &'a mut [u8]) -> Result<&'a str, ()> { // 将char编码为UTF-8字节 let ch_bytes = ch.encode_utf8(&mut [0u8; 4]).as_bytes(); let total_len = ch_bytes.len() + s.len(); // 缓冲区长度不足返回错误 if buf.len() < total_len { return Err(()); } // 先后拷贝两个内容到缓冲区 buf[..ch_bytes.len()].copy_from_slice(ch_bytes); buf[ch_bytes.len()..total_len].copy_from_slice(s.as_bytes()); // 安全:两段内容都是合法UTF-8,拼接后也合法 Ok(unsafe { core::str::from_utf8_unchecked(&buf[..total_len]) }) } // 使用示例 fn test_concat() { let mut buf = [0u8; 128]; // 可根据shell最大输入长度调整缓冲区大小 let result = concat_char_and_str('你', "好世界", &mut buf).unwrap(); assert_eq!(result, "你好世界"); }
如果可以引入第三方no_std兼容依赖,也可以用arrayvec的ArrayString简化代码,不用手动处理缓冲区拷贝:
use arrayvec::ArrayString; use core::fmt::Write; fn concat_char_and_str(ch: char, s: &str) -> ArrayString<128> { let mut buf = ArrayString::<128>::new(); buf.write_char(ch).unwrap(); buf.write_str(s).unwrap(); buf }
方案2:基于堆分配实现(已开启alloc库的场景适用)
如果你已经完成了Philipp Opperman教程中的内核堆分配器实现,并且开启了alloc crate,可以直接使用alloc库的String完成拼接:
extern crate alloc; use alloc::string::String; fn concat_char_and_str(ch: char, s: &str) -> String { let mut res = String::with_capacity(ch.len_utf8() + s.len()); res.push(ch); res.push_str(s); res }
注意事项
- 不要默认char占1字节,Rust的char是Unicode标量值,UTF-8编码长度为1~4字节,必须调用
encode_utf8或者len_utf8方法处理编码,避免非ASCII字符拼接乱码。 - 嵌入式shell场景下优先选择栈缓冲区方案,只需将缓冲区大小设置为你期望支持的shell命令最大长度即可,完全满足常规使用需求。
内容的提问来源于stack exchange,提问作者Lap
相关产品推荐
相关产品推荐

