2017-06-22 57 views
5

Mục đích ban đầu của tôi là chuyển đổi một số nguyên thủy đã ký thành biểu diễn thập lục phân của nó theo cách giữ dấu của số. Nó chỉ ra rằng việc triển khai hiện tại của LowerHex, UpperHex và người thân đối với các số nguyên nguyên thủy đã ký sẽ đơn giản coi chúng là unsigned. Bất kể những cờ định dạng bổ sung mà tôi thêm vào, những triển khai này xuất hiện đơn giản là diễn giải lại số đó như là đối tác không dấu của nó cho các mục đích định dạng. (Playground)Làm cách nào để định dạng một số nguyên đã ký thành biểu diễn thập lục phân nhận biết ký hiệu?

println!("{:X}", 15i32);   // F 
println!("{:X}", -15i32);   // FFFFFFF1 (expected "-F") 
println!("{:X}", -0x80000000i32); // 80000000 (expected "-80000000") 
println!("{:+X}", -0x80000000i32); // +80000000 
println!("{:+o}", -0x8000i16);  // +100000 
println!("{:+b}", -0x8000i16);  // +1000000000000000 

Các tài liệu trong std::fmt là không rõ ràng về việc này là vụ xảy ra, hoặc thậm chí còn có giá trị, và UpperHex (hoặc bất kỳ đặc điểm định dạng khác) không đề cập rằng việc triển khai cho các số nguyên ký giải thích số không dấu. Dường như không có vấn đề nào liên quan đến kho lưu trữ GitHub của Rust.

Cuối cùng, người ta có thể thực hiện các chức năng cụ thể cho nhiệm vụ (như dưới đây), với nhược điểm không may là không tương thích với API định dạng.

fn to_signed_hex(n: i32) -> String { 
    if n < 0 { 
     format!("-{:X}", -n) 
    } else { 
     format!("{:X}", n) 
    } 
} 

assert_eq!(to_signed_hex(-15i32), "-F".to_string()); 

Hành vi này cho các loại số nguyên có chữ ký có chủ ý không? Có cách nào để thực hiện quy trình định dạng này trong khi vẫn tuân thủ tiêu chuẩn Formatter không?

Trả lời

4

Có cách nào để thực hiện quy trình định dạng này trong khi vẫn tuân thủ tiêu chuẩn Formatter không?

Có, nhưng bạn cần tạo một loại mới để cung cấp triển khai riêng biệt UpperHex. Dưới đây là một thực hiện tôn trọng các +, #0 cờ (và có thể nhiều hơn, tôi đã không kiểm tra):

use std::fmt::{self, Formatter, UpperHex}; 

struct ReallySigned(i32); 

impl UpperHex for ReallySigned { 
    fn fmt(&self, f: &mut Formatter) -> fmt::Result { 
     let prefix = if f.alternate() { "0x" } else { "" }; 
     let bare_hex = format!("{:X}", self.0.abs()); 
     f.pad_integral(self.0 >= 0, prefix, &bare_hex) 
    } 
} 

fn main() { 
    for &v in &[15, -15] { 
     for &v in &[&v as &UpperHex, &ReallySigned(v) as &UpperHex] { 
      println!("Value: {:X}", v); 
      println!("Value: {:08X}", v); 
      println!("Value: {:+08X}", v); 
      println!("Value: {:#08X}", v); 
      println!("Value: {:+#08X}", v); 
      println!(); 
     } 
    } 
} 
+0

Tôi thề truy cập vào các tùy chọn định dạng không sử dụng để có mặt ở đó, nhưng có vẻ như họ đã ở đó từ 1.5.0, nên tôi không biết tôi đang nghĩ gì. – Shepmaster

+0

Vâng ['flags()'] (https://doc.rust-lang.org/nightly/std/fmt/struct.Formatter.html#method.flags) luôn ở đó, nó chỉ là "mà bit là gì "không thực sự được ghi lại ... –

Các vấn đề liên quan