关于print、printf、println的区别不做介绍
只关注 printf的参数格式

整数格式化符%d

package main

import (
	"fmt"
)

func main() {
	fmt.Printf("1,2,4,5,6,7,8,9,10\n")
	fmt.Printf("%9d\n", 18)
	fmt.Printf("%09d\n", 18)
	fmt.Printf("%-9d\n", 18)
	fmt.Printf("%-09d", 18)
}
  • 第一行1到10做为参照....
  • 第 2 行中格式化符%9d表示要保证输出的整数有 9 位,如果不到 9 位则在左侧补上空格字符,直至一共有 9 个字符为止,左侧的确是空了 7 个字符的位置。
  • 如果想要左对齐,可以在宽度标志符前增加一个减号字符 "-"。
  • 左侧可以用数字 "0" 来补齐空位,只需要在宽度标识符前加一个数字 "0" 即可。
  • 右侧补数字 "0",是无效的。因为从数学意义上来说,在整数右侧补0会使数值发生变化。

十六进制格式化符%x%X

如果需要用十六进制表示整数,可以使用%x%X格式化符。这两者都是将整数按十六进制形式输出,唯一区别的是%x输出的是小写字符而%X输出的是大写字符。%x%X 也支持宽度标识符和左右对齐

func main() {
	fmt.Printf("%9x\n", 65535)
	fmt.Printf("%09x\n", 65535)
	fmt.Printf("%-9x\n", 65535)
	fmt.Printf("%-09x", 65535)
}

二进制格式化符%b

类似于十六进制格式化符%x%X%b可以以二进制的形式将整数表达出来

func main() {
	fmt.Printf("%9b\n", 10)
	fmt.Printf("%09b\n", 10)
	fmt.Printf("%-9b\n", 10)
	fmt.Printf("%-0b", 10)
}

浮点数格式化符%f

func main() {
	a := 1.23456789
	fmt.Printf("%f\n", a)     // 显示浮点数,不做精细控制
	fmt.Printf("%9.2f\n", a)  // %9.2f,要求整体输出9个字符,其中,小数点后输出2个字符
	fmt.Printf("%9.6f\n", a)  // %9.6f,要求整体输出9个字符,其中,小数点后输出6个字符
	fmt.Printf("%09.2f\n", a) // %09.2f,要求整体输出9个字符,不足补0,其中,小数点后输出2个字符,超过的部分四舍五入处理后输出
	b := 8.888888888
	fmt.Printf("%09.2f\n", b) // %09.2f,要求整体输出9个字符,不足补0,其中,小数点后输出2个字符,超过的部分四舍五入处理后输出
	fmt.Printf("%-9.2f\n", a) // %-9.2f,要求整体输出9个字符,左对齐,其中,小数点后输出2个字符
	fmt.Printf("%9.9f\n", a)  // %9.9f,要求整体输出9个字符,其中,小数点后输出9个字符
	fmt.Printf("%9.09f", a)   // %9.9f,要求整体输出9个字符,其中,小数点后输出9个字符
}
  • 与整数的宽度标识符是一个整数数字不同,浮点数的宽度标识符一般是一个小数,小数点前的部分表示要求输出的整体宽度是几个字符,小数点后的部分表示要求输出的小数点后面的位数。
  • 整体字符位数可以省略,比如格式化符 "0.2f",可以输出小数点后 2 位,总数根据需要而定的浮点数

其他浮点数格式化符

还有一些并不常用的浮点数格式化符,以及一些用于表示复数的格式化符。

  • %b也可以用于表示任意数字(包括小数)的二进制形式,实际上表示的是该数字对应 2 的多少次方乘以一个数字,类似科学计数法中将 e 的值从 10 转换成 2
  • %e%E则代表用科学计数法表示一个浮点数,两者的区别在于结果中的字母 e 是大写还是小写
  • %g%G则是根据浮点数后小数点的位数自动决定是否用科学计数法表示,如果位数少就用%f的方式表示,否则根据字母 g 的大小写分别对应%e%E的方式显示,整体原则是尽量减少数字中无用的 0 来简洁输出的位数
func main() {
	fmt.Printf("%b\n", 2.0)
	fmt.Printf("%b\n", 1.0)
	fmt.Printf("%b\n", 0.1)

	fmt.Printf("%e\n", 2.0/3)
	fmt.Printf("%E\n", 2.0/3)
	fmt.Printf("%e\n", 8.0)

	fmt.Printf("%g\n", 3.0/700000)
	fmt.Printf("%G\n", 2.0/3)
	fmt.Printf("%G", 8.0)
}

布尔类型的格式符%t

布尔类型的数据或变量可以用格式化符%t来控制输出,输出信息是truefalse两个字符串

func main() {
	a := true
	b := false
	fmt.Printf("a: %t,b: %t,a==b: %t", a, b, a == b)
}

输出结果:

a: true,b: false,a==b: false

Unicode 码相关格式化符%c%q%U

格式化符%c%q的作用是将后面的整数参数作为一个字符的编码来看待并输出该编码对应的 Unicode 字符,两者的区别在于%q会将输出的字符用单引号括起来。而格式化符%U与这两者正好想相反,是将后面作为参数的字符(注意需用英文单引号 ' 括起来)的 Unicode 编码(确切地说是 UTF-8 编码)输出

func main() {
	fmt.Printf("%c\n", 0x61)
	fmt.Printf("%q\n", 0x61)
	fmt.Printf("%U\n", 'a')
	fmt.Printf("%U", "a")
}


可以看出,第四行是有报警告的%!U(string=a)

字符串格式化符%s

简单,不解释

func main() {
	fmt.Printf("%s is aaa", "我是")
}

输出

我是 is aaa

指针格式化符%p

格式化符%p用于输出指针的值,由于 Go 语言中为了代码安全尽量弱化了指针的存在,因此这个格式化符并不常用

func main() {
	a := "abc"
	b := []int{1, 2, 3}
	p := &b
	fmt.Printf("a的地址: %p,b的地址: %p", &a, p)
}

输出:

a的地址: 0xc000014250,b的地址: 0xc000010030

万能格式化符%v

%v这个是格式化符是 Go 语言中的一个比较有用的改进。使用%v格式化符,可以对包括符合类型在内的绝大多数数据类型按照默认格式输出。这样可以避免我们编程时再去关注输出数据的具体类型并按其类型确定格式化符。
%v可以理解:对整数而言等同于%d,对浮点数而言等同于%g,对布尔类型数据而言等同于%t,对字符串而言等同于%s,对指针而言等同于%p
%#v字符可以输出数据在 Go 语言中的表达形式,主要用于编程中调试程序。

输出参数类型%T

func main() {
	a := 1
	b := "hello"

	fmt.Printf("a : %T \n", a)
	fmt.Printf("b : %T \n", b)
}

输出

a : int 
b : string 
动词 功能
%v 按值的本来值输出
%+v 在 %v 的基础上,对结构体字段名和值进行展开
%#v 输出 Go 语言语法格式的值
%T 输出 Go 语言语法格式的类型和值
%% 输出 %% 本体
%b 整型以二进制方式显示
%o 整型以八进制方式显示
%d 整型以十进制方式显示
%x 整型以 十六进制显示
%X 整型以十六进制、字母大写方式显示
%U Unicode 字符
%f 浮点数
%p 指针,十六进制方式显示