Go 练习题 序列化和反序列化

1、day1

1.1、使用结构体统计文件内字符个数

go 复制代码
func main() {
	fileName := "/Users/zld/goproject/abc.txt"
	file, err := os.Open(fileName)
	if err != nil {
		fmt.Printf("open file err %v\n", err)
		return

	}
	defer file.Close()
	var count CharCount
	reader := bufio.NewReader(file)
	for {
		str, err := reader.ReadString('\n')
		if err == io.EOF {
			break
		}

		for _, v := range str {
			switch {
			case v >= 'a' && v <= 'z':
				fallthrough
			case v >= 'A' && v <= 'Z':
				count.ChCount++
			case v == ' ' || v == '\t':
				count.SpaceCount++
			case v >= '0' && v <= '9':
				count.NumCount++
			default:
				count.OtherCount++
			}
		}

		fmt.Printf("字符的个数为=%v,\n数字的个数=%v,\n空格的个数为=%v,\n其他字符的个数为=%v", count.ChCount, count.NumCount, count.SpaceCount, count.OtherCount)

	}
}
bash 复制代码
cat /Users/zld/goproject/abc.txt 
    da klk;lkl;kl;klkek ``                              123  lkal;ekldk                         `` ``
bash 复制代码
go build count.go 
bash 复制代码
go run count.go 
字符的个数为=24,
数字的个数=3,
空格的个数为=21,
其他字符的个数为=11

1.2、获取命令行所有参数

go 复制代码
package main

import (
	"fmt"
	"os"
)

func main() {
	fmt.Println("命令行的参数有", len(os.Args))
	for i, v := range os.Args {
		fmt.Printf("args[%v]=%v\n", i, v)
	}
}
bash 复制代码
go run args.go ddd bb dad -a ad
命令行的参数有 6
args[0]=/var/folders/1t/6cgnk_j12h9fmvb8_xgs2ych0000gn/T/go-build513664270/b001/exe/args
args[1]=ddd
args[2]=bb
args[3]=dad
args[4]=-a
args[5]=ad

1.3、flag 包解析命令行参数

go 复制代码
package main

import (
	"flag"
	"fmt"
)

func main() {
	var user string
	var host string
	var port int
	var pwd string
	flag.StringVar(&user, "u", "", "用户名,默认为空")
	flag.StringVar(&host, "h", "", "主机,默认为空")
	flag.StringVar(&pwd, "pwd", "localhost", "密码,默认为 localhost")
	flag.IntVar(&port, "port", 3306, "端口号,默认为 3306")
	//必须调用这个方法,具体使用方法参考文档 https://studygolang.com/pkgdoc
	flag.Parse()
	fmt.Printf("user=%v,\nhost=%v,\npwd=%v,\nport=%v", user, host, port, pwd)
}
bash 复制代码
go run flag.go -u=test -h=172.18.0.1 -port 990 -pwd 123456
user=test,
host=172.18.0.1,
pwd=990,
port=123456

1.4、 对数据类型进行序列化

go 复制代码
package main

import (
	"encoding/json"
	"fmt"
)

type Monster struct {
	Name     string
	Age      int
	Birthday string
	Sal      float64
	Skill    string
}

func testStruct() {
	monster := Monster{
		Name:     "牛魔王",
		Age:      500,
		Birthday: "2011-10-10",
		Sal:      8000.0,
		Skill:    "牛魔拳",
	}
	//将 monster 序列化
	data, err := json.Marshal(&monster)
	if err != nil {
		fmt.Printf("序列化失败 error%v", err)
	}
	fmt.Printf("monster 序列化后%v\n", string(data))

}

// 将 map 序列化
func testMap() {
	//定义一个 map
	var a map[string]interface{}
	//使用map之前需要 make
	a = make(map[string]interface{})
	a["name"] = "红孩儿"
	a["age"] = 30
	a["address"] = "洪崖洞"
	//map 是引用类型,不需要传入指针,直接传入 a 即可
	data, err := json.Marshal(&a)
	if err != nil {
		fmt.Printf("序列化失败 error%v", err)
	}
	fmt.Printf("a 序列化后%v\n", string(data))

}

// 演示对切片进行序列化

func testSlice() {
	var slice []map[string]interface{}
	var m1 map[string]interface{}
	m1 = make(map[string]interface{})
	m1["name"] = "jack"
	m1["age"] = 7
	m1["address"] = "北京"
	slice = append(slice, m1)
	var m2 map[string]interface{}
	m2 = make(map[string]interface{})
	m2["name"] = "tom"
	m2["age"] = 9
	m2["address"] = [2]string{"墨西哥", "夏威夷"}
	slice = append(slice, m2)
	//将切片进行序列化操作
	data, err := json.Marshal(&slice)
	if err != nil {
		fmt.Printf("序列化失败 error%v", err)
	}
	fmt.Printf("slice 序列化后%v\n", string(data))

}

// 对基本(普通)数据类型序列化
func testFloat64() {
	var num1 float64 = 2345.67
	data, err := json.Marshal(&num1)
	if err != nil {
		fmt.Printf("序列化失败 error%v", num1)
	}
	fmt.Printf("num1 序列化后%v", string(data))
}
func main() {
	// 可以验证数据类型是否符合 json 格式的网站 https://www.json.cn/
	// 演示将结构体/map/切片 序列化
	testStruct()
	// map 序列化后是无序的
	testMap()
	// 切片序列化
	testSlice()
	// 基本(普通)数据类型序列化
	testFloat64()

}
bash 复制代码
go run serialization.go 
monster 序列化后{"Name":"牛魔王","Age":500,"Birthday":"2011-10-10","Sal":8000,"Skill":"牛魔拳"}
a 序列化后{"address":"洪崖洞","age":30,"name":"红孩儿"}
slice 序列化后[{"address":"北京","age":7,"name":"jack"},{"address":["墨西哥","夏威夷"],"age":9,"name":"tom"}]
num1 序列化后2345.67

1.5、序列化 struct 时 tag 使用

当希望指定 struct 被序列化后的 key 时候,使用 struct tag 的方式(反射机制)。

go 复制代码
package main

import (
	"encoding/json"
	"fmt"
)

type Monster struct {
	Name     string `json:"monster_name"`
	Age      int    `json:"monster_age"`
	Birthday string
	Sal      float64
	Skill    string
}

func testStruct() {
	monster := Monster{
		Name:     "牛魔王",
		Age:      500,
		Birthday: "2011-10-10",
		Sal:      8000.0,
		Skill:    "牛魔拳",
	}
	//将 monster 序列化
	data, err := json.Marshal(&monster)
	if err != nil {
		fmt.Printf("序列化失败 error%v", err)
	}
	fmt.Printf("monster 序列化后%v\n", string(data))

}

// // 将 map 序列化
// func testMap() {
// 	//定义一个 map
// 	var a map[string]interface{}
// 	//使用map之前需要 make
// 	a = make(map[string]interface{})
// 	a["name"] = "红孩儿"
// 	a["age"] = 30
// 	a["address"] = "洪崖洞"
// 	//map 是引用类型,不需要传入指针,直接传入 a 即可
// 	data, err := json.Marshal(&a)
// 	if err != nil {
// 		fmt.Printf("序列化失败 error%v", err)
// 	}
// 	fmt.Printf("a 序列化后%v\n", string(data))

// }

// // 演示对切片进行序列化

// func testSlice() {
// 	var slice []map[string]interface{}
// 	var m1 map[string]interface{}
// 	m1 = make(map[string]interface{})
// 	m1["name"] = "jack"
// 	m1["age"] = 7
// 	m1["address"] = "北京"
// 	slice = append(slice, m1)
// 	var m2 map[string]interface{}
// 	m2 = make(map[string]interface{})
// 	m2["name"] = "tom"
// 	m2["age"] = 9
// 	m2["address"] = [2]string{"墨西哥", "夏威夷"}
// 	slice = append(slice, m2)
// 	//将切片进行序列化操作
// 	data, err := json.Marshal(&slice)
// 	if err != nil {
// 		fmt.Printf("序列化失败 error%v", err)
// 	}
// 	fmt.Printf("slice 序列化后%v\n", string(data))

// }

// // 对基本(普通)数据类型序列化
//
//	func testFloat64() {
//		var num1 float64 = 2345.67
//		data, err := json.Marshal(&num1)
//		if err != nil {
//			fmt.Printf("序列化失败 error%v", num1)
//		}
//		fmt.Printf("num1 序列化后%v", string(data))
//	}
func main() {
	// 可以验证数据类型是否符合 json 格式的网站 https://www.json.cn/
	// 演示将结构体/map/切片 序列化
	testStruct()
	// map 序列化后是无序的
	// testMap()
	// // 切片序列化
	// testSlice()
	// // 基本(普通)数据类型序列化
	// testFloat64()

}
bash 复制代码
go run serialization.go 
monster 序列化后{"monster_name":"牛魔王","monster_age":500,"Birthday":"2011-10-10","Sal":8000,"Skill":"牛魔拳"}

1.5、对json进行反序列化

go 复制代码
package main

import (
	"encoding/json"
	"fmt"
)

// 将json反序列化成结构体
// 定义一个结构体
type Monster struct {
	Name     string `json:"monster_name"`
	Age      int    `json:"monster_age"`
	Birthday string
	Sal      int
	Skill    string
}

func unmarshalStruct() {
	str := "{\"monster_name\":\"牛魔王\",\"monster_age\":500,\"Birthday\":\"2011-10-10\",\"Sal\":8000,\"Skill\":\"牛魔拳\"}"
	//定义一个 monster实例
	var monster Monster
	err := json.Unmarshal([]byte(str), &monster)
	if err != nil {
		fmt.Printf("unmarshal err=%v\n", err)
	}
	fmt.Printf("反序列化后 monster=%v\n", monster)
}

// 将json反序列化成map
var a map[string]interface{}

// 注意:反序列化map 不需要make,因为make操作被封装到 json.Unmarshal 函数
func unmarshalMap() {
	str := "{\"address\":\"洪崖洞\",\"age\":30,\"name\":\"红孩儿\"}"
	//定义一个map
	//var a map[string]interface{}
	//反序列化
	err := json.Unmarshal([]byte(str), &a)
	if err != nil {
		fmt.Printf("unmalshal err=%v\n", err)
	}
	fmt.Printf("反序列化后 a=%v\n", a)
}

// 将 json 反序列化成 slice
func unmarshalSlice() {
	str := "[{\"address\":\"北京\",\"age\":7,\"name\":\"jack\"}," +
		"{\"address\":[\"墨西哥\",\"夏威夷\"],\"age\":9,\"name\":\"tom\"}]"
		//定义一个 slice
	var slice []map[string]interface{}
	//反序列化,不需要make,因为make操作被封装到 json.Unmarshal 函数
	err := json.Unmarshal([]byte(str), &slice)
	if err != nil {
		fmt.Printf("unmarshal err=%v\n", err)
	}
	fmt.Printf("反序列化后 slice=%v\n", slice)

}
func main() {
	unmarshalStruct()
	unmarshalMap()
	unmarshalSlice()

}

运行结果

go 复制代码
go run unmarshal.go 
反序列化后 monster={牛魔王 500 2011-10-10 8000 牛魔拳}
反序列化后 a=map[address:洪崖洞 age:30 name:红孩儿]
反序列化后 slice=[map[address:北京 age:7 name:jack] map[address:[墨西哥 夏威夷] age:9 name:tom]]
相关推荐
007php00711 小时前
GoZero 上传文件File到阿里云 OSS 报错及优化方案
服务器·开发语言·数据库·python·阿里云·架构·golang
高 朗13 小时前
【GO基础学习】基础语法(2)切片slice
开发语言·学习·golang·slice
IT书架13 小时前
golang面试题
开发语言·后端·golang
醒过来摸鱼19 小时前
【Golang】协程
开发语言·后端·golang
灼华十一21 小时前
算法编程题-排序
数据结构·算法·golang·排序算法
宋发元1 天前
Go语言使用 kafka-go 消费 Kafka 消息教程
golang·kafka·linq
宋发元1 天前
Go消费kafka中kafkaReader.FetchMessage(ctx)和kafkaReader.ReadMessage(ctx)的区别
golang·kafka·linq
祁许1 天前
【Golang】手搓DES加密
开发语言·golang·密码学
凡人的AI工具箱1 天前
15分钟学 Go 实战项目六 :统计分析工具项目(30000字完整例子)
开发语言·数据库·人工智能·后端·golang
王大锤43911 天前
golang通用后台管理系统10(退出登录,注销token)
golang