环境搭建
创建D:/zdpgo目录,将zdpgo_yaml解压到这个目录。
创建D:/zdpgo/demo目录。
初始化模块:
go mod init demo
使用vscode打开。
code .
修改 go.mod
module demo
go 1.22
require zdpgo_yaml v0.1.0
replace zdpgo_yaml v0.1.0 => ../zdpgo_yaml
写入yaml文件
编写一个Go程序,将以下数据写入到config.yaml文件中。
data := map[string]interface{} {
"name": "源滚滚编程",
"age": 33,
"email": "ygg@example.com"
}
期望的输出结果:
name: 源滚滚编程
age: 33
email: ygg@example.com
示例代码:
package main
import (
"fmt"
"os"
yaml "zdpgo_yaml"
)
func main() {
data := map[string]interface{}{
"name": "源滚滚编程",
"age": 33,
"email": "ygg@example.com",
}
// 转换为yaml
yamlData, err := yaml.Marshal(data)
if err != nil {
fmt.Println("转换为yaml失败:", err)
return
}
// 写入文件
err = os.WriteFile("config.yaml", yamlData, 0644)
if err != nil {
fmt.Println("写入yaml文件失败:", err)
return
}
// 成功
fmt.Println("写入yaml文件成功")
}
代码分析:
数据准备,使用map[string]interface{}这种数据结构准备yaml数据,这种方式简单灵活。
序列化,使用yaml.Marshal方法将Go语言的数据结构转换为yaml文件格式的字节切片。
写入文件,使用os.WriteFile将yaml数据写入到文件,0644是文件的全新,表示所有者可读,可写,其他用户可读。
错误处理,无论是在转换的时候,还是写入的时候,我们都加入了错误处理的代码,让程序更加的健壮。
写入嵌套的yaml
核心代码:
package main
import (
"fmt"
"os"
yaml "zdpgo_yaml"
)
func main() {
data := map[string]interface{}{
"server": map[string]interface{}{ // 服务器配置
"host": "127.0.0.1", // 主机地址
"port": 8080, // 端口号
"timeout": "30s", // 超时时间
},
"database": map[string]interface{}{ // 数据库配置
"host": "127.0.0.1",
"port": 3306,
"username": "root",
"password": "root",
"database": "zdpgo_yaml",
},
}
// 转换为yaml
yamlData, err := yaml.Marshal(data)
if err != nil {
fmt.Println("转换为yaml格式失败:", err)
return
}
// 写入到文件
err = os.WriteFile("config.yaml", yamlData, 0644)
if err != nil {
fmt.Println("写入到yaml文件失败:", err)
return
}
// 成功
fmt.Println("写入到yaml文件成功!")
}
输出结果:
database:
database: zdpgo_yaml
host: 127.0.0.1
password: root
port: 3306
username: root
server:
host: 127.0.0.1
port: 8080
timeout: 30s
读取yaml文件
假设我们有config.yaml文件如下:
name: 源滚滚编程
age: 33
使用Go语言读取这个yaml配置文件并输出所有的值。
示例代码:
package main
import (
"fmt"
"os"
yaml "zdpgo_yaml"
)
type Config struct {
Name string `yaml:"name"`
Age int `yaml:"age"`
}
func main() {
// 读取文件
// os.ReadFile 不会打开文件句柄,可以不用使用 Close 关闭
yamlFile, err := os.ReadFile("config.yaml")
if err != nil {
fmt.Println("读取yaml文件失败:", err)
return
}
// 解析
var config Config
err = yaml.Unmarshal(yamlFile, &config)
if err != nil {
fmt.Println("解析yaml失败:", err)
return
}
// 成功了
fmt.Println(config.Name)
fmt.Println(config.Age)
}
修改yaml文件
假设我们有config.yaml文件如下:
name: 源滚滚编程
age: 33
使用Go语言解析这个配置文件,并将name修改为“张大鹏”。
示例代码:
package main
import (
"fmt"
"os"
yaml "zdpgo_yaml"
)
type Config struct {
Name string `yaml:"name"`
Age int `yaml:"age"`
}
func main() {
// 读取
yamlData, err := os.ReadFile("config.yaml")
if err != nil {
fmt.Println("读取yaml失败:", err)
return
}
// 解析
var config Config
err = yaml.Unmarshal(yamlData, &config)
if err != nil {
fmt.Println("解析yaml失败:", err)
return
}
// 解析成功
fmt.Println("解析成功:", config.Name, config.Age)
// 修改
config.Name = "张大鹏"
// 转换为yaml
newData, err := yaml.Marshal(&config)
if err != nil {
fmt.Println("转换yaml失败:", err)
return
}
// 保存
err = os.WriteFile("config.yaml", newData, 0644)
if err != nil {
fmt.Println("保存yaml失败:", err)
return
}
// 成功
fmt.Println("保存yaml成功!")
}
解析嵌套的yaml
假设有config.yaml配置文件如下:
app:
name: "MyApp"
version: "1.0.0"
server:
host: "localhost"
port: 8080
database:
enabled: true
connection:
host: "localhost"
port: 3306
username: "root"
password: "root"
db: "test"
使用Go语言解析这个yaml文件,并输出数据库的IP地址是多少,以及服务端端口号是多少?
示例代码:
package main
import (
"fmt"
"os"
yaml "zdpgo_yaml"
)
type Config struct {
App ConfigApp `yaml:"app"`
Server ConfigServer `yaml:"server"`
Database ConfigDatabase `yaml:"database"`
}
type ConfigApp struct {
Name string `yaml:"name"`
Vresion string `yaml:"version"`
}
type ConfigServer struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
}
type ConfigDatabase struct {
Enabled bool `yaml:"enabled"`
Connection ConfigDatabaseConnection `yaml:"connection"`
}
type ConfigDatabaseConnection struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
Username string `yaml:"username"`
Password string `yaml:"password"`
DB string `yaml:"db"`
}
func main() {
// 读取文件
yamlData, err := os.ReadFile("config.yaml")
if err != nil {
fmt.Println("读取yaml失败:", err)
return
}
// 解析
var config Config
err = yaml.Unmarshal(yamlData, &config)
if err != nil {
fmt.Println("解析yaml失败:", err)
return
}
// 成功
fmt.Println("数据库的IP地址", config.Database.Connection.Host)
fmt.Println("服务端端口号", config.Server.Host)
}
修改嵌套的yaml
假设有一个config.yaml配置文件,内容如下:
app:
name: "MyApp"
version: "1.0.0"
server:
host: "localhost"
port: 8080
database:
enabled: true
connection:
host: "localhost"
port: 3306
username: "root"
password: "root"
db: "test"
把 server.port 改为 8888,把 database.connection.host 改成 192.168.33.33。
示例代码:
package main
import (
"fmt"
"os"
yaml "zdpgo_yaml"
)
type Config struct {
App ConfigApp `yaml:"app"`
Server ConfigServer `yaml:"server"`
Database ConfigDatabase `yaml:"database"`
}
type ConfigApp struct {
Name string `yaml:"name"`
Version string `yaml:"version"`
}
type ConfigServer struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
}
type ConfigDatabase struct {
Enabled bool `yaml:"enabled"`
Connection ConfigDatabaseConnection `yaml:"connection"`
}
type ConfigDatabaseConnection struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
Username string `yaml:"username"`
Password string `yaml:"password"`
DB string `yaml:"db"`
}
func main() {
// 读取yaml
yamlData, err := os.ReadFile("config.yaml")
if err != nil {
fmt.Println("读取yaml失败:", err)
return
}
// 解析yaml
var config Config
err = yaml.Unmarshal(yamlData, &config)
if err != nil {
fmt.Println("解析yaml失败:", err)
return
}
// 修改yaml
// 把 server.port 改为 8888
config.Server.Port = 8888
// 把 database.connection.host 改成 192.168.33.33。
config.Database.Connection.Host = "192.168.33.33"
// 保存yaml
newData, err := yaml.Marshal(&config)
if err != nil {
fmt.Println("转换yaml失败:", err)
return
}
err = os.WriteFile("config.yaml", newData, 0644)
if err != nil {
fmt.Println("保存yaml失败:", err)
return
}
// 成功
fmt.Println("保存yaml成功!")
}
解析数组
假设有config.yaml文件,内容如下:
name: 源滚滚编程
age: 33
hobbies:
- 篮球
- 足球
- 羽毛球
- 乒乓球
使用Go语言解析这个yaml配置文件,并输出有哪些兴趣爱好。
示例代码:
package main
import (
"fmt"
"os"
yaml "zdpgo_yaml"
)
type Config struct {
Name string `yaml:"name"`
Age int `yaml:"age"`
Hobbies []string `yaml:"hobbies"`
}
func main() {
// 读取
yamlData, err := os.ReadFile("config.yaml")
if err != nil {
fmt.Println("读取yaml失败:", err)
return
}
// 解析
var config Config
err = yaml.Unmarshal(yamlData, &config)
if err != nil {
fmt.Println("解析yaml失败:", err)
return
}
// 输出
fmt.Println(config.Hobbies)
}
提取特定字段
假设有一个config.yaml配置文件,内容如下:
name: 源滚滚编程
age: 33
contact:
email: "ygg@example.com"
phone: "18811112222"
address:
province: "重庆市"
city: "重庆市"
使用go语言,解析这个yaml文件,提取出用户名的电话和所处城市。
示例代码:
package main
import (
"fmt"
"os"
yaml "zdpgo_yaml"
)
type Config struct {
Name string `yaml:"name"`
Age int `yaml:"age"`
Contact ConfigContact `yaml:"contact"`
Address ConfigAddress `yaml:"address"`
}
type ConfigContact struct {
Email string `yaml:"email"`
Phone string `yaml:"phone"`
}
type ConfigAddress struct {
Province string `yaml:"province"`
City string `yaml:"city"`
}
func main() {
// 读取文件
yamlData, err := os.ReadFile("config.yaml")
if err != nil {
fmt.Println("读取yaml失败:", err)
return
}
// 解析
var config Config
err = yaml.Unmarshal(yamlData, &config)
if err != nil {
fmt.Println("解析yaml失败:", err)
return
}
// 提取:手机号,城市
fmt.Println("手机号:", config.Contact.Phone)
fmt.Println("城市:", config.Address.City)
}
练习1
假设有一个config.yaml文件,内容如下:
menu:
- name: "宫保鸡丁"
type: "主菜"
price: 38
flavors: ["辣", "咸"]
- name: "清蒸鲈鱼"
type: "主菜"
price: 58
flavors: ["鲜", "清淡"]
- name: "扬州炒饭"
type: "主食"
price: 22
flavors: ["香", "甜"]
- name: "麻婆豆腐"
type: "主菜"
price: 28
flavors: ["辣", "麻"]
请编写一个Go程序,完成以下任务:
读取并解析config.yaml文件
提取并打印所有主菜的名称和价格
提取并打印所有包含“辣”口味的菜的名称
示例代码:
package main
import (
"fmt"
"os"
yaml "zdpgo_yaml"
)
// 菜单
type Menu struct {
Dishes []Dish `yaml:"menu"`
}
// 菜品
type Dish struct {
Name string `yaml:"name"` // 菜名
Type string `yaml:"type"` // 类型
Price int `yaml:"price"` // 价格
Flavors []string `yaml:"flavors"` // 口味
}
func main() {
// 读取
yamlData, err := os.ReadFile("config.yaml")
if err != nil {
fmt.Println("读取yaml失败:", err)
return
}
// 解析
var menu Menu
err = yaml.Unmarshal(yamlData, &menu)
if err != nil {
fmt.Println("解析yaml失败:", err)
return
}
// 提取并打印所有主菜的名称和价格
fmt.Println("所有主菜的名称和价格")
for _, dish := range menu.Dishes {
if dish.Type == "主菜" {
fmt.Printf("名称:%s,价格:%d元\n", dish.Name, dish.Price)
}
}
// 提取并打印所有包含“辣”口味的菜的名称
fmt.Println("所有包含“辣”口味的菜的名称")
for _, dish := range menu.Dishes {
for _, flavor := range dish.Flavors {
if flavor == "辣" {
fmt.Println(dish.Name)
break
}
}
}
}
练习2
department:
name: "研发部"
manager: "张三"
employees:
- name: "李四"
position: "高级工程师"
age: 32
skills:
- "Go"
- "Python"
- "Docker"
- name: "王五"
position: "初级工程师"
age: 25
skills:
- "Go"
- "JavaScript"
- name: "赵六"
position: "测试工程师"
age: 28
skills:
- "自动化测试"
- "性能测试"
请编写一个Go程序,完成以下任务:
读取并解析config.yaml文件
打印部门名称和经理的姓名
找出掌握“Go”技能的员工的姓名和职位
计算部门员工的平均年龄
示例代码:
package main
import (
"fmt"
"os"
yaml "zdpgo_yaml"
)
// 配置信息
type Config struct {
Department ConfigDepartment `yaml:"department"`
}
// 部门信息
type ConfigDepartment struct {
Name string `yaml:"name"` // 部门名
Manager string `yaml:"manager"` // 负责人
Employees []Employee `yaml:"employees"`
}
// 员工信息
type Employee struct {
Name string `yaml:"name"` // 姓名
Position string `yaml:"position"` // 职位
Age int `yaml:"age"` // 年龄
Skills []string `yaml:"skills"` // 技能
}
func main() {
// 读取
yamlData, err := os.ReadFile("config.yaml")
if err != nil {
fmt.Println("读取yaml文件失败:", err)
return
}
// 解析
var config Config
err = yaml.Unmarshal(yamlData, &config)
if err != nil {
fmt.Println("解析yaml失败:", err)
return
}
// 打印部门名称和经理的姓名
fmt.Printf("部门名称:%s,经理姓名:%s\n", config.Department.Name, config.Department.Manager)
// 找出掌握“Go”技能的员工的姓名和职位
fmt.Println("掌握Go技能的有:")
for _, employee := range config.Department.Employees {
for _, skill := range employee.Skills {
if skill == "Go" {
fmt.Println(employee.Name, employee.Position)
break
}
}
}
// 计算部门员工的平均年龄
avgAge := 0
sumAge := 0
employeeLength := 0
for _, employee := range config.Department.Employees {
sumAge += employee.Age
employeeLength++
}
avgAge = sumAge / employeeLength
fmt.Println("平均年龄:", avgAge)
}
领取专属 10元无门槛券
私享最新 技术干货