一个普通人想将一个字节打印为2个十六进制数字,例如10
应该给0x0a
。在Rust中,人们会使用类似println!("{:#02x}", 10)
的东西,但它会给出0xa
。
我尝试过的事情列表(使用来自std::fmt
和fmt::LowerHex
的信息以及一些StackOverflow问题):
println!("{:#02x}", 10);
println!("{:#0x}", 10);
println!("{:#x}", 10);
println!("{:#x?}", 10);
println!("{:#0x?}", 10);
println!("{:#02x?}", 10);
它们全部输出0xa
,而不是0x0A
的预期行为。
此问题已被编辑(消除了相关的情绪),随后被标记为其他问题的重复。但是其他答案不能解决为什么上面的列表不起作用。 #
格式选项会导致意外的输出(0xa
),特别是02
令人惊讶地根本没有效果!没有其他问题着眼了这个,尤其是#
上也是如此。
答案 0 :(得分:6)
如std::fmt
模块中所述:
#
-此标志指示应使用“备用”打印形式。替代形式为:
#x
-在参数前加0x#X
-在参数前加0x
这与请求宽度交互,因为宽度占整个的替代,因此0x0a
是 4 个字符,而不是2个字符。
如果您请求的宽度小于必要宽度,则忽略请求的宽度,而使用最小宽度(此处为3个字符)。
快速实验on the playground:
fn main() {
println!("{:#01x}", 10);
println!("{:#02x}", 10);
println!("{:#03x}", 10);
println!("{:#04x}", 10);
println!("{:#05x}", 10);
println!("{:#06x}", 10);
}
打印:
0xa
0xa
0xa
0x0a
0x00a
0x000a
一切都很好。
答案 1 :(得分:-1)
如果您使用:
println!("10 is 0x{:02x} in hex", 10); // ==> "0x0a"
代替:
println!("10 is {:#02x} in hex", 10); // "0xa"
有效。
但是,正如评论者所指出的那样,这不是错误,而是对02
的含义感到困惑。这并不意味着有效位数的最小数目,而是最小的字符总数,现在必须包含0x
。因此这也可以:
println!("10 is {:#04x} in hex", 10); // "0x0a"
但是此解决方案和将其推广为“正确”解决方案的文化存在问题。
首先请注意,从0x
到#
的引入包括总宽度的概念。一个人需要在精神上减去2才能得到有效位数,这是有效位数。不管04
会将10000格式设置为{:#04x}
,它占用6个字符,而不是4个字符。因此,总宽度的概念失败了,作为一个概念,也许太简单了。
此外,0x2710
,{:#03x}
和{:#02x}
都容易引起与`{:#x}相同的行为,尽管它们使编译器(1.35)不对其进行标记没有意义,并指出一个错误。
第二,{:#01x}
格式器仅对特定于Rust的数字表示有用,例如插入#
而不插入0x
(另一种常见的十六进制表示格式)。
非常重要的是,总宽度的概念只有在使用$
格式化程序时才变得明确(然后在普通字节情况下静默失败)。 #
格式程序表示Rust具有该选项来考虑总宽度,并且在应用总宽度时(在固定宽度布局的情况下)应该使用它。
其余部分说明了为什么#
是一种特殊情况的解决方案,以及为什么在一般情况下不建议使用它。
应根据上下文选择格式化程序字符串,尤其是在选择的格式表示意图时,具体如何考虑在该上下文中显示数字。因此:
#
专注于总宽度,在进行固定宽度固定表格布局时很有用。在这种情况下,{:#04x}
格式化程序显然是符合人体工程学的。 #
在生成自定义格式字符串(给定宽度的上下文)时,例如在输出需要按需从十六进制更改为二进制(例如,从{:#04x}
到{{1 }}),尽管很难想象具体的案例。
{:#04x}
表示有效数字的数量,在主要关注点是如何在有限的空间内表示一行信息时,此数字很有用。在这种情况下,常见的修改是删除{:#04b}
。使用0x{02x}
可以简单地删除0x
,而使用0x{:02x}
格式化程序则需要同时删除0x
并将{:#04}
替换为{{1} }。两种情况下的最终结果是相同的:#
,但是04
需要概念上的转变。
根据情况,02
格式化程序是符合人体工程学的,并且可以表达意图。使用与您要实现的目标相符的格式。但是在一般情况下,最好将{:02x}
视为相对模糊的功能。仅在定义明确的情况下才需要其附加的智能功能。
不幸的是,其他答案建议将#
作为默认值,“正确”或“可靠解决方案”。但是,某些功能(#
)可用这一事实并不意味着:
-Rust认可它,否则建议使用它,
-总宽度的基本概念需要表达,或
-总宽度的概念应推广到所有Rust格式表达式(这是大多数答案所显示的根本问题)
总而言之,提供了#
的锈迹,但是{:#04x}
仍然通常更简单,更关键并且得到普遍认可。它是KISS,没有隐藏的缺陷。