text - 我该如何使用格式!no_std 环境中的宏?
问题描述
如何在不使用 std 的情况下实现以下示例?
let text = format!("example {:.1} test {:x} words {}", num1, num2, num3);
text
具有类型&str
和num1
,num2
并且num3
具有任何数字类型。
我尝试使用numtoa
anditoa/dtoa
来显示数字,但numtoa
不支持浮点数并且itoa
不支持no_std
. 我觉得在字符串中显示一个数字是相当普遍的,而且我可能遗漏了一些明显的东西。
解决方案
除了Shepmaster 的答案之外,您还可以在没有分配器的情况下格式化字符串。
在core::fmt::Write
你只需要实施write_str
,然后你就write_fmt
可以免费获得。
使用format_args!(...)
(与 相同的语法format!
)您可以准备一个core::fmt::Arguments
值,该值可以传递给core::fmt::write
.
见操场:
#![crate_type = "dylib"]
#![no_std]
pub mod write_to {
use core::cmp::min;
use core::fmt;
pub struct WriteTo<'a> {
buffer: &'a mut [u8],
// on write error (i.e. not enough space in buffer) this grows beyond
// `buffer.len()`.
used: usize,
}
impl<'a> WriteTo<'a> {
pub fn new(buffer: &'a mut [u8]) -> Self {
WriteTo { buffer, used: 0 }
}
pub fn as_str(self) -> Option<&'a str> {
if self.used <= self.buffer.len() {
// only successful concats of str - must be a valid str.
use core::str::from_utf8_unchecked;
Some(unsafe { from_utf8_unchecked(&self.buffer[..self.used]) })
} else {
None
}
}
}
impl<'a> fmt::Write for WriteTo<'a> {
fn write_str(&mut self, s: &str) -> fmt::Result {
if self.used > self.buffer.len() {
return Err(fmt::Error);
}
let remaining_buf = &mut self.buffer[self.used..];
let raw_s = s.as_bytes();
let write_num = min(raw_s.len(), remaining_buf.len());
remaining_buf[..write_num].copy_from_slice(&raw_s[..write_num]);
self.used += raw_s.len();
if write_num < raw_s.len() {
Err(fmt::Error)
} else {
Ok(())
}
}
}
pub fn show<'a>(buffer: &'a mut [u8], args: fmt::Arguments) -> Result<&'a str, fmt::Error> {
let mut w = WriteTo::new(buffer);
fmt::write(&mut w, args)?;
w.as_str().ok_or(fmt::Error)
}
}
pub fn test() {
let mut buf = [0u8; 64];
let _s: &str = write_to::show(
&mut buf,
format_args!("write some stuff {:?}: {}", "foo", 42),
).unwrap();
}
推荐阅读
- visual-studio - 如何在flutter中使用pjsip?
- r - R`t.test`问题导致`159等于8875`
- python - onedrivesdk 未使用 pip 安装
- amazon-web-services - 如何从 cloudwatch 日志中提取时间值以执行数学运算
- audio - ubuntu 18.04 没有声音
- javascript - 如何使用javascript覆盖ubuntu中的默认cmd快捷键
- java - Joda-time,期间计算问题?
- sage-erp - 如何在 SAGE 中从外部系统创建 IC 内部使用条目?
- angular - 角料表检测滚动
- python-3.x - 尝试在 pycharam 中使用 sys