3.5.2.格式化整数
现在我们将介绍整数的格式化,从二进制(基数为2)的输出开始。
1 | fmt.Printf("|%b|%9b|%-9b|%09b|% 9b|\n", 37, 37, 37, 37, 37) |
1 | |100101|···100101|100101···|000100101|···100101| |
第一个格式(%b)使用了%b(二进制)格式化动作并使用尽可能少的数字将整数以二进制的形式输出。第二个格式(%9b)指定要输出的长度为9个字符(如有必要将超出此长度来避免截断),且默认右对齐。第三个格式(%-9b)使用“-”修饰符即输出设置为左对齐。第四个格式(%09b)使用0作为填充符,第五个格式(% 9b)使用空格作为填充符。
八进制的格式化类似于二进制,但支持另一种格式。它使用%o(八进制)格式化动作。
1 | fmt.Printf("|%o|%#o|%# 8o|%#+ 8o|%+08o|\n", 41, 41, 41, 41, -41) |
1 | |51|051|·····051|····+051|-0000051| |
可以使用#修饰符启用另一种格式,从而在输出的时候以0开头。+修饰符会强制输出该符号,如果没有该修饰符,输出正数时前面没有“+”号。
十六进制格式使用%x 和%X(十六进制)格式化动作,它们指定了是否以小写字母还是大写字母来表示A-F。
1 2 3 | i := 3931 fmt.Printf("|%x|%X|%8x|%08x|%#04X|0x%04X|\n", i, i, i, i, i, i) |
1 | |f5b|F5B|·····f5b|00000f5b|0X0F5B|0x0F5B| |
对于十六进制数字,替换格式修饰符(#)会导致以0x或者0X开头输出。同样对于所有的数字,如果我们指定了一个超过我们所需的宽度,输出时将会以给定的宽度输出额外的空格来将数字右对齐,而如果我们指定的宽度太小,则将其全部输出,所以没有截断的风险。
十进制数字使用%d(十进制)格式化动作输出。唯一可用于填充的字符是空格和0,但是也可以使用自定义的函数来使用其它的字符进行填充。
1 2 3 | i = 569 fmt.Printf("|$%d|$%06d|$%+06d|$%s|\n", i, i, i, Pad(i, 6, '*')) |
1 | |$569|$000569|$+00569|$***569| |
最后我们使用%s格式化动作来打印一个字符串切片,该切片也是Pad()函数所返回的。
1 2 3 4 5 6 7 8 | func Pad(number, width int, pad rune) string { s := fmt.Sprint(number) gap := width - utf8.RuneCountInString(s) if gap > 0 { return strings.Repeat(string(pad), gap) + s } return s } |
utf8.RuneCountInString() 函数返回给定字符串的字符个数;它总是小于或等于其字节个数。strings.Repeat()函数接收一个字符串和一个整数并返回一个新的字符串,该字符串由给定的字符串重复给定次数所产生。我们选择以rune类型(即Unicode码点)的方式传递填充符来避免该函数的使用者传递一个包含多个字符的字符串。