一.fmt
fmt包实现了类似C语言printf和scanf的格式化I/O。主要分为向外输出内容和获取输入内容两大部分。
1.1 向外输出
标准库fmt提供了以下几种输出相关函数。
Print系列函数会将内容输出到系统的标准输出,区别在于Print函数直接输出内容,没有换行符,Printf函数支持格式化输出字符串,Println函数会在输出内容的结尾添加一个换行符。
func Print(a ...interface{}) (n int, err error)
func Printf(format string, a ...interface{}) (n int, err error)
func Println(a ...interface{}) (n int, err error)
举个简单的例子:
- Fprint
Fprint系列函数会将内容输出到一个io.Writer接口类型的变量w中,我们通常用这个函数往文件中写入内容。
func Fprint(w io.Writer, a ...any) (n int, err error)
func Fprintf(w io.Writer, format string, a ...any) (n int, err error)
func Fprintln(w io.Writer, a ...any) (n int, err error)
举个例子:
注意:只要满足io.Writer接口的类型都支持写入。
- Sprint
Sprint系列函数会把传入的数据生成并返回一个字符串。
func Sprint(a ...any) string
func Sprintf(format string, a ...any) string
func Sprintln(a ...any) string
- Errorf
Errorf函数根据format参数生成格式化字符串并返回一个包含该字符串的错误。
func Errorf(format string, a ...any) error
通常使用这种方式来自定义错误类型:
1.2 格式化占位符
*printf 系列函数都支持format格式化参数,在这里我们按照占位符将被替换的变量类型划分,方便查询和记忆。
- 通用占位符
- 布尔型
- 整形
- 浮点数和复数
- 字符串和[]byte
- 指针
- 宽度标识符
宽度通过一个紧跟在百分号后面的十进制数指定,如果未指定宽度,则表示值是处必须之外不作填充。精度通过(可选的)宽度后跟点号后跟十进制数指定。如果未指定精度,会使用默认精度如果点号后没有跟数字,表示精度为0。
宽度的意思就是长度。
- 其它flag
1.3 获取输入
Go语言fmt包下有fmt.Scan,fmt.Scanf,fmt.Scanln三个函数,可以在程序运行过程中从标准输入获取用户输入。
- fmt.Scan
函数签名如下:
func Scan(a ...any) (n int, err error)
- Scan从标准输入扫描文本,读取由空白符分隔的值保存到传递本函数的参数中,换行符视为空白符。
- 本函数返回成功扫描的数据个数和遇到任何错误。如果读取的数据个数比提供的参数少,会返回一个错误报告原因。
示例:
fmt.Scan从标准输入中扫描用户输入的数据,将空白符分隔的数据分别存入指定参数。
- fmt.Scanf
函数签名如下:
func Scanf(format string, a ...any) (n int, err error)
- Scanf从标准输入扫描文本,根据format参数指定的格式取读取由空白符分隔的值保存到传递给本函数的参数中。
- 本函数返回成功扫描的数据个数和遇到任何错误。
fmt.Scanf不同于fmt.Scan简单的以空格作为输入数据的空格符,fmt.Scanf为输入数据指定了具体输入内容格式,只有按照格式输入数据才会被扫描并存入对应变量。
- fmt.Scanln
函数签名如下:
func Scanln(a ...any) (n int, err error)
- Scanln类似Scan,它在遇到换行时才停止扫描。最后一个数据后面必须有换行或者到达结束位置。
- 本函数返回成功扫描的数据个数和遇到任何错误。
- bufio.NewReader
有时候我们想完整获取输入的内容,而输入的内容可能包含空格,这种情况可以使用bufio包来实现。
scan系列函数会把空格符作为分隔符,不会读上来。
- Fscan系列
这几个功能分别类似于fmt.Scan,fmt.Scanf,fmt.Scanln三个函数,只不过它们不是从标准输入中读取数据而是从io.Reader中读取数据。
func Fscan(r io.Reader, a ...interface{}) (n int, err error)
func Fscanln(r io.Reader, a ...interface{}) (n int, err error)
func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error)
- Sscan系列
这几个函数的功能分别类似于fmt.Scan,fmt.Scanf,fmt.Scanln三个函数,只不过他们不是从标准输入中读取数据而是从指定字符串中读取数据。
func Sscan(str string, a ...interface{}) (n int, err error)
func Sscanln(str string, a ...interface{}) (n int, err error)
func Sscanf(str string, format string, a ...interface{}) (n int, err error)
二. Time包
time包提供了时间的显示和测量用的函数。日历的计算采用的是公历。
2.1 时间类型
time.Time 类表示时间。我们可以使用time.Now()函数获取当前的时间对象,然后获取时间对象的年月日时分秒等信息。
2.2 时间戳
时间戳是自1970年1月1日(08:00:00GMT)至当前时间的总毫秒数。它也被成为Unix时间戳(UnixTimestamp)。
基于时间对象获取时间戳的示例代码如下:
使用time.Unix()函数可以将时间戳转为时间格式。
2.3 时间间隔
time.Duration是time包定义的一个类型,它代表两个时间点之间经过的时间,以纳秒为单位。
time.Duration表示一段时间间隔,可表示的最长时间段大约290年。
time包中定义的时间间隔类型的常量如下:
例如:time.Duration表示1纳秒,time.Second表示1秒。
2.4 时间操作
- Add
我们在日常的编码过程中可能会遇到要求时间+时间间隔的需求,Go语言的时间对象有提供Add方法:
func (t Time) Add(d Duration) Time
举个例子,求一个小时后的时间:
- Sub
求两个时间之间的差值。
func (t Time) Sub(u Time) Duration
返回一个时间段t-u。如果结果超出了Duration可以表示的最大值/最小值,将返回最大值/最小值。要获取时间点t-d(d为Duration),可以使用t.Add(-d)。
- Equal
- Before
- After
2.5 定时器
使用time.Tick(时间间隔)来设置定时器,定时器本质上是一个通道(channel)。
2.6 时间格式化
时间格式化输出,时间类型有一个自带的方法Format进行格式化,需要注意的是Go语言中格式化时间模板不是常见的Y-m-d H:M:S而是使用Go的诞生时间2006年1月2号15点04分(记忆口诀为2006 1 2 3 4)。
补充:如果想格式化为12小时方式,需要指定PM。
- 解析字符串格式的时间