Ответ 1
Руст 1.26.0 и выше
The :x?
Форматер "debug with шестнадцатеричные целые" может использоваться:
let data = b"hello";
println!("{:x?}", data);
println!("{:X?}", data);
[68, 65, 6c, 6c, 6f]
[68, 65, 6C, 6C, 6F]
Его также можно комбинировать с модификатором pretty:
let data = b"hello";
println!("{:#x?}", data);
println!("{:#X?}", data);
[
0x68,
0x65,
0x6c,
0x6c,
0x6f
]
[
0x68,
0x65,
0x6C,
0x6C,
0x6F
]
Если вам нужно больше контроля или поддержка старых версий Rust, продолжайте читать.
Руст 1.0 и выше
use std::fmt::Write;
fn main() {
let mut s = String::new();
for &byte in "Hello".as_bytes() {
write!(&mut s, "{:X} ", byte).expect("Unable to write");
}
println!("{}", s);
}
Это можно представить, реализовав одну из особенностей форматирования (fmt::Debug
, fmt::Display
, fmt::LowerHex
, fmt::UpperHex
и т.д.) В структуре и имея небольшой конструктор:
use std::fmt;
struct HexSlice<'a>(&'a [u8]);
impl<'a> HexSlice<'a> {
fn new<T>(data: &'a T) -> HexSlice<'a>
where T: ?Sized + AsRef<[u8]> + 'a
{
HexSlice(data.as_ref())
}
}
// You can even choose to implement multiple traits, like Lower and UpperHex
impl<'a> fmt::Display for HexSlice<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for byte in self.0 {
// Decide if you want to pad out the value here
write!(f, "{:X} ", byte)?;
}
Ok(())
}
}
fn main() {
// To get a 'String'
let s = format!("{}", HexSlice::new("Hello"));
// Or print it directly
println!("{}", HexSlice::new("world"));
// Works with
HexSlice::new("Hello"); // string slices (&str)
HexSlice::new(b"Hello"); // byte slices (&[u8])
HexSlice::new(&"World".to_string()); // References to String
HexSlice::new(&vec![0x00, 0x01]); // References to Vec<u8>
}