这段笔记详细讲解了Go语言中常用的标准库,包括 fmt 包用于格式化输出,encoding/json 包用于 JSON 数据的序列化与反序列化,time 包用于时间操作,strconv 包用于字符串与数值类型转换,os 和 os/exec 包用于操作系统交互。每个部分通过代码示例展示了如何处理常见的编程任务,如格式化输出、处理 JSON 数据、计算时间差、转换数据类型、管理环境变量及执行系统命令等。这些工具适用于调试、数据处理、自动化脚本编写、与系统交互等场景。请根据目录快速检索和入门。
走进 Go 语言基础语法
01-fmt
package main
import "fmt"
type point struct {
x, y int
}
func main() {
s := "hello"
n := 123
p := point{1, 2}
fmt.Println(s, n) // hello 123
fmt.Println(p) // {1 2}
fmt.Printf("s=%v\n", s) // s=hello
fmt.Printf("n=%v\n", n) // n=123
fmt.Printf("p=%v\n", p) // p={1 2}
fmt.Printf("p=%+v\n", p) // p={x:1 y:2}
fmt.Printf("p=%#v\n", p) // p=main.point{x:1, y:2}
f := 3.141592653
fmt.Println(f) // 3.141592653
fmt.Printf("%.2f\n", f) // 3.14
}
核心知识点:
这段代码展示了Go语言中 fmt 包的格式化输出函数,包括基本的数据打印、结构体的详细输出以及浮点数的格式化。fmt 包提供了强大的格式化功能,可以控制输出内容的形式,以适应不同的输出需求。
基本语法:
fmt.Println(...): 基础输出函数,用于打印数据并换行,适合简单的数据打印。fmt.Printf(...): 格式化输出函数,支持占位符,可以控制输出内容的格式:%v: 打印变量的值,适合通用打印。%+v: 打印结构体时,会显示字段名和值,便于了解结构体详细内容。%#v: 打印变量的 Go 语法表示,特别有助于调试复杂数据类型,例如结构体。%.2f: 格式化浮点数,保留小数点后两位。
应用场景:
- 基本打印:
fmt.Println用于简单、直观的输出,适合调试和日志打印等场景。 - 格式化输出:
fmt.Printf用于需要更精细控制的输出,例如调试输出结构体详细信息、格式化数字、控制小数精度等,常用于生成标准化报告、日志或者人机接口输出。 - 结构体调试:
%+v和%#v特别适合用来调试复杂数据结构,能够更清楚地展示结构体的字段和值。
02-json
package main
import (
"encoding/json"
"fmt"
)
type userInfo struct {
Name string
Age int `json:"age"`
Hobby []string
}
func main() {
a := userInfo{Name: "wang", Age: 18, Hobby: []string{"Golang", "TypeScript"}}
buf, err := json.Marshal(a)
if err != nil {
panic(err)
}
fmt.Println(buf) // [123 34 78 97...]
fmt.Println(string(buf)) // {"Name":"wang","age":18,"Hobby":["Golang","TypeScript"]}
buf, err = json.MarshalIndent(a, "", "\t")
if err != nil {
panic(err)
}
fmt.Println(string(buf))
var b userInfo
err = json.Unmarshal(buf, &b)
if err != nil {
panic(err)
}
fmt.Printf("%#v\n", b) // main.userInfo{Name:"wang", Age:18, Hobby:[]string{"Golang", "TypeScript"}}
}
核心知识点:
这段代码展示了Go语言中 encoding/json 包的使用,包括结构体序列化和反序列化。序列化(Marshal)将数据转换为 JSON 格式,反序列化(Unmarshal)将 JSON 转换为相应的 Go 数据结构。通过结构体标签可以自定义 JSON 字段的名称。
基本语法:
type userInfo struct { ... }: 定义了一个结构体userInfo,用于表示用户信息。Age int \json:"age"`: 使用结构体标签为json包指定字段名称映射。字段Age在 JSON 中会显示为"age"`。json.Marshal(a): 将结构体a转换为 JSON 字节切片,适用于数据的网络传输或保存。json.MarshalIndent(a, "", "\t"): 格式化输出 JSON,增加缩进以便于阅读,常用于日志或调试。json.Unmarshal(buf, &b): 反序列化,将 JSON 字节切片buf转换为结构体b,&b表示将解析后的数据存储到结构体变量b中。
应用场景:
- 数据序列化:
Marshal和MarshalIndent适用于将结构体、映射等数据类型转换为 JSON 格式,用于 API 请求响应、数据持久化等场景。 - 结构体标签:可以通过标签自定义 JSON 字段名称,确保输出的 JSON 格式符合需求,例如与外部 API 兼容。
- 数据解析:
Unmarshal用于将 JSON 数据解析为 Go 结构体,常用于处理外部系统的数据输入、配置文件解析等。
03-time
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
fmt.Println(now) // 2022-03-27 18:04:59.433297 +0800 CST m=+0.000087933
t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
t2 := time.Date(2022, 3, 27, 2, 30, 36, 0, time.UTC)
fmt.Println(t) // 2022-03-27 01:25:36 +0000 UTC
fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute()) // 2022 March 27 1 25
fmt.Println(t.Format("2006-01-02 15:04:05")) // 2022-03-27 01:25:36
diff := t2.Sub(t)
fmt.Println(diff) // 1h5m0s
fmt.Println(diff.Minutes(), diff.Seconds()) // 65 3900
t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36")
if err != nil {
panic(err)
}
fmt.Println(t3 == t) // true
fmt.Println(now.Unix()) // 1648738080
}
核心知识点:
这段代码展示了Go语言中的 time 包的使用,包括时间的创建、格式化、时间差计算、解析和时间戳获取等功能。time 包提供了丰富的时间操作函数,适用于处理和管理日期和时间。
基本语法:
now := time.Now(): 获取当前时间,返回Time对象。t := time.Date(...): 使用具体的年、月、日、时、分、秒、纳秒和时区信息创建一个时间对象。t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(): 获取时间对象的各个组成部分,如年、月、日、时、分。t.Format("2006-01-02 15:04:05"): 格式化时间为指定的字符串格式,注意2006-01-02 15:04:05是 Go 语言的标准时间模板,代表特定格式。t2.Sub(t): 计算两个时间对象之间的差值,返回一个Duration对象。diff.Minutes(), diff.Seconds(): 获取时间差的分钟数和秒数。time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36"): 将字符串解析为时间对象,使用标准时间模板。now.Unix(): 获取当前时间的 Unix 时间戳(自 1970 年 1 月 1 日以来的秒数)。
应用场景:
- 获取和创建时间:
time.Now和time.Date用于获取当前时间或创建特定时间对象,适合需要标记时间点或记录事件的场景。 - 时间格式化与解析:
Format和Parse适用于时间的输入输出操作,将时间转换为特定字符串格式,或从字符串转换为时间对象,例如日志记录和日期解析。 - 时间差计算:
Sub函数用于计算两个时间点之间的差值,适合测量时间间隔,例如计算执行时间、定时任务等。 - Unix 时间戳:
Unix函数用于获取秒级时间戳,适合需要与其他系统进行时间同步、比较或保存数据的场景。
04-strconv
package main
import (
"fmt"
"strconv"
)
func main() {
f, _ := strconv.ParseFloat("1.234", 64)
fmt.Println(f) // 1.234
n, _ := strconv.ParseInt("111", 10, 64)
fmt.Println(n) // 111
n, _ = strconv.ParseInt("0x1000", 0, 64)
fmt.Println(n) // 4096
n2, _ := strconv.Atoi("123")
fmt.Println(n2) // 123
n2, err := strconv.Atoi("AAA")
fmt.Println(n2, err) // 0 strconv.Atoi: parsing "AAA": invalid syntax
}
核心知识点:
这段代码展示了Go语言中 strconv 包的使用,包括字符串到数值类型的转换。strconv 包提供了将字符串转换为各种数值类型的功能,同时也支持将数值转换为字符串。在数值转换时,还会返回错误值用于检查是否成功。
基本语法:
strconv.ParseFloat("1.234", 64): 将字符串"1.234"转换为浮点数,64表示返回的浮点数为float64类型。strconv.ParseInt("111", 10, 64): 将字符串"111"转换为整数,10表示十进制,64表示返回的整数类型为int64。strconv.ParseInt("0x1000", 0, 64):0表示根据字符串的前缀自动判断进制(0x表示十六进制)。strconv.Atoi("123"): 将字符串"123"转换为整数,Atoi是ParseInt的简单封装,适用于十进制字符串。strconv.Atoi("AAA"): 当字符串不能被转换为整数时,返回0和错误对象err,可以用于判断转换是否成功。
应用场景:
- 数值转换:
strconv适用于从字符串中提取数值的情况,例如处理用户输入、读取配置文件或解析JSON数据等。 - 错误处理:转换函数返回一个
error,在转换失败时可以捕获并处理错误,适合需要数据验证和防止输入错误的场景。 - 多种数值类型支持:支持浮点数、整数(包括不同进制)等多种数值类型转换,适合处理各种数据类型之间的转换需求。
05-env
package main
import (
"fmt"
"os"
"os/exec"
)
func main() {
// go run example/20-env/main.go a b c d
fmt.Println(os.Args) // [/var/folders/8p/n34xxfnx38dg8bv_x8l62t_m0000gn/T/go-build3406981276/b001/exe/main a b c d]
fmt.Println(os.Getenv("PATH")) // /usr/local/go/bin...
fmt.Println(os.Setenv("AA", "BB"))
buf, err := exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput()
if err != nil {
panic(err)
}
fmt.Println(string(buf)) // 127.0.0.1 localhost
}
核心知识点:
这段代码展示了Go语言中的 os 和 os/exec 包的使用,用于处理环境变量、命令行参数以及执行系统命令。os 包可以用来与操作系统交互,而 os/exec 包提供了执行外部系统命令的功能。
基本语法:
os.Args: 获取命令行参数,返回一个字符串切片,包含程序名及其传入的参数。os.Getenv("PATH"): 获取指定环境变量的值,如PATH环境变量。os.Setenv("AA", "BB"): 设置环境变量AA的值为BB,通常用于临时配置程序运行环境。exec.Command("grep", "127.0.0.1", "/etc/hosts").CombinedOutput(): 使用exec.Command执行系统命令,例如调用grep查找/etc/hosts文件中的内容。CombinedOutput()用于捕获命令执行后的标准输出和错误输出。
应用场景:
- 命令行参数处理:通过
os.Args处理命令行参数,适合编写需要从命令行接收参数的脚本或命令行工具。 - 环境变量操作:
os.Getenv和os.Setenv用于读取和设置环境变量,适合对运行环境进行配置,或者访问系统信息。 - 执行外部命令:
exec.Command用于执行操作系统级别的命令,例如调用其他可执行程序、执行 shell 脚本等,常用于自动化操作、测试、集成等场景。
这种功能对于编写系统工具、自动化脚本或者与系统级别操作交互非常有用,可以通过Go程序轻松管理和运行外部任务。