讓我們先從標準版本:
use std::io::Write;
fn main() {
let x = 123;
let mut buf = [0 as u8; 20];
write!(&mut buf[..], "{}", x).expect("Can't write");
assert_eq!(&buf[0..3], b"123");
}
如果我們再取出標準庫:
#![feature(lang_items)]
#![no_std]
#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "panic_fmt"] extern fn panic_fmt() -> ! { loop {} }
fn main() {
let x = 123;
let mut buf = [0 as u8; 20];
write!(&mut buf[..], "{}", x).expect("Can't write");
assert_eq!(&buf[0..3], b"123");
}
我們得到的錯誤
error: no method named `write_fmt` found for type `&mut [u8]` in the current scope
--> src/main.rs:13:5
|
13 | write!(&mut buf[..], "{}", x).expect("Can't write");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in a macro from the standard library
write_fmt
在覈心中實現圖書館由core::fmt::Write
。如果我們實現它自己,我們都能夠通過該錯誤:
#![feature(lang_items)]
#![feature(start)]
#![no_std]
extern crate libc;
#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "panic_fmt"] extern fn panic_fmt() -> ! { loop {} }
use core::fmt::{self, Write};
struct Wrapper<'a> {
buf: &'a mut [u8],
offset: usize,
}
impl<'a> Wrapper<'a> {
fn new(buf: &'a mut [u8]) -> Self {
Wrapper {
buf: buf,
offset: 0,
}
}
}
impl<'a> fmt::Write for Wrapper<'a> {
fn write_str(&mut self, s: &str) -> fmt::Result {
let bytes = s.as_bytes();
// Skip over already-copied data
let remainder = &mut self.buf[self.offset..];
// Make the two slices the same length
let remainder = &mut remainder[..bytes.len()];
// Copy
remainder.copy_from_slice(bytes);
Ok(())
}
}
#[start]
fn start(_argc: isize, _argv: *const *const u8) -> isize {
let x = 123;
let mut buf = [0 as u8; 20];
write!(Wrapper::new(&mut buf), "{}", x).expect("Can't write");
assert_eq!(&buf[0..3], b"123");
0
}
需要注意的是,我們正在複製的io::Cursor
的行爲納入此包裝。通常,對&mut [u8]
的多次寫入將相互覆蓋。這對重用分配很有用,但在連續寫入相同數據時無用。
然後這只是一個寫宏的問題,如果你想。
這需要'self.offset + = bytes.len();'在write_str()中,否則這是有效的。想知道爲什麼格式化浮點只打印小數部分。 –