Go-04| 豆包MarsCode AI 刷题”

123 阅读9分钟

这段笔记详细讲解了Go语言中常用的标准库,包括 fmt 包用于格式化输出,encoding/json 包用于 JSON 数据的序列化与反序列化,time 包用于时间操作,strconv 包用于字符串与数值类型转换,osos/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 中。

应用场景:

  • 数据序列化MarshalMarshalIndent 适用于将结构体、映射等数据类型转换为 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.Nowtime.Date 用于获取当前时间或创建特定时间对象,适合需要标记时间点或记录事件的场景。
  • 时间格式化与解析FormatParse 适用于时间的输入输出操作,将时间转换为特定字符串格式,或从字符串转换为时间对象,例如日志记录和日期解析。
  • 时间差计算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" 转换为整数,AtoiParseInt 的简单封装,适用于十进制字符串。
  • 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语言中的 osos/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.Getenvos.Setenv 用于读取和设置环境变量,适合对运行环境进行配置,或者访问系统信息。
  • 执行外部命令exec.Command 用于执行操作系统级别的命令,例如调用其他可执行程序、执行 shell 脚本等,常用于自动化操作、测试、集成等场景。

这种功能对于编写系统工具、自动化脚本或者与系统级别操作交互非常有用,可以通过Go程序轻松管理和运行外部任务。