2022-5-23 实习Day42

1、黑名单放行入表数据不完整,调试后端代码,找到漏填字段添加入表–3小时 100%
2、业务执行流程协助测试及bug查找–3小时 100%

Golang编程学习(part 37)

1、命令行参数

我们如果希望能够获取到命令行输入的各种参数,该如何处理?如图:命令行参数
1
D:\goproject\src\go_code>test.exe tom c:/aa/bb/config.init 88
① 基本介绍

os.Args是一个string切片, 用来存储所有的命令行参数

1
2
3
4
5
6
func main() {
fmt.Println("命令行的参数有", len(os.Args))
for i, v := range os.Args {
fmt.Printf("args[%v]=%v\n", i, v)
}
}
1
2
3
4
5
6
PS E:\GoLand2022.1\PROJECT\Test1\IO> .\TestIO.exe tomcat 888 true
命令行的参数有 4
args[0]=E:\GoLand2022.1\PROJECT\Test1\IO\TestIO.exe
args[1]=tomcat
args[2]=888
args[3]=true
② flag包用来解析命令行参数
说明:前面的方式是比较原生的方式,对解析参数不是特别的方便,特别是带有指定参数形式的命令行。
比如:cmd>main.exe -f c:/aaa.txt -p 200 -u root 这样形式的命令行,go设计者给我们提供了flag包,可以方便的解析命令行参数,而且参数顺序可以随意
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func main() {
// 定义几个变量,用于接收命令行的参数值
var user string
var pwd string
var host string
var port int

// &user 就是接收用户命令行中输入的 -u 后面的参数值
// "u" ,就是 -u 指定参数
// "" ,默认值
// "用户名,默认为空" 说明
flag.StringVar(&user, "u", "", "用户名, 默认为空")
flag.StringVar(&pwd, "pwd", "", "密码, 默认为空")
flag.StringVar(&host, "h", "localhost", "主机名, 默认为localhost")
flag.IntVar(&port, "port", 3306, "端口号, 默认为3306")

// 这里有一个非常重要的操作,转化,必须调用该方法
flag.Parse()

// 输出结果
fmt.Printf("user=%v pwd=%v host=%v port=%v", user, pwd, host, port)
}
1
2
PS E:\GoLand2022.1\PROJECT\Test1\IO> .\TestIO.exe -u 周杰伦 -pwd 123 -h 127.168.1.1 -port 6379
user=周杰伦 pwd=123 host=127.168.1.1 port=6379

2、json基本介绍

概述:JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。key-val
JSON是在2001年开始推广使用的数据格式,目前已经成为主流的数据格式
JSON易于机器解析和生成,并有效地提升网络传输效率,通常程序在网络传输时会先将数据(结构体、map等)序列化成json字符串,到接收方得到json字符串时,再反序列化恢复成原来的数据类型(结构体、map等)。这种方式已然成为各个语言的标准
1
2
3
4
5
|————————————|         |———————————|          |———————|          |——————————|
| | 序列化 | | 网络传输 | | 反序列化 | |
| Golang |———————> | json字符串 |—————————>| 程序 |————————> | 其他语言 |
| | | | | | | |
|————————————| |———————————| |———————| |——————————|

image-20220601231857352

① json数据格式说明
在JS语言中,一切都是对象。因此,任何的数据类型都可以通过JSON来表示,例如字符串、数字、对象、数组、map、结构体等(任何数据类型都可以转成json格式)
JSON键值对是用来保存数据的一种方式,键值对组合中的键名写在前面并用双引号””包裹,使用冒号:分割,然后紧接着值:[{“key1”:val,”key2”:val2,”key3”:val3,”key4”:[val4,val5]},{“key1”:val,”key2”:val2,”key3”:val3,”key4”:[val4,val5]}]
② json数据在线解析
http://www.json.cn/ 网站可以验证一个json格式的数据是否正确。尤其是在我们编写比较复杂的json格式数据时很有用

3、 json的序列化

json序列化是指将有key-value结构的数据类型(比如结构体、map、切片)序列化成json字符串的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// 将结构体序列化
package main

import (
"encoding/json"
"fmt"
)

// 定义一个结构体
type Monster struct {
Name string
Age int
Birthday string
Sal float64
Skill string
}

func main() {
monster := Monster{
Name: "牛魔王",
Age: 500,
Birthday: "1500-11-11",
Sal: 8000,
Skill: "牛魔拳",
}

// 将monster序列化
marshal, err := json.Marshal(&monster)

if err != nil {
fmt.Println("序列化错误err=%v\n", err)
}
// 输出序列化的结果
fmt.Println(string(marshal))
}

// {"Name":"牛魔王","Age":500,"Birthday":"1500-11-11","Sal":8000,"Skill":"牛魔拳"}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 将map进行序列化
func main() {
// 定义一个map
var a map[string]interface{}

// 使用map需要先make
a = make(map[string]interface{})
a["name"] = "红孩儿"
a["age"] = 30
a["address"] = "洪崖洞"
a["skill"] = "喷火"

// 将a这个map进行序列化
marshal, err := json.Marshal(a)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(marshal))
}

// {"address":"洪崖洞","age":30,"name":"红孩儿","skill":"喷火"}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 对切片进行序列化
func main() {
var slice []map[string]interface{}

m1 := make(map[string]interface{})
m1["name"] = "jack"
m1["age"] = 7
m1["address"] = "北京"
slice = append(slice, m1)

m2 := make(map[string]interface{})
m2["name"] = "tom"
m2["age"] = 20
m2["address"] = []string{"墨西哥", "夏威夷"}
slice = append(slice, m2)

// 将切片进行序列化操作data
marshal, err := json.Marshal(slice)
if err != nil {
fmt.Println(err)
}

// 输出序列化后的结果
fmt.Println(string(marshal))
}

// [{"address":"北京","age":7,"name":"jack"},{"address":["墨西哥","夏威夷"],"age":20,"name":"tom"}]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 对基本数据类型进行序列化, 对基本数据类型进行序列化意义不大
func main() {

var num float64 = 2345.9

marshal, err := json.Marshal(num)
if err != nil {
fmt.Println(err)
return
}

fmt.Println(string(marshal))
}

// 2345.9

④ 结构体序列化的注意事项
对于结构体序列化,如果我们希望序列化后的key的名字由我们自己重新制定,那么可以给struct指定一个tag标签
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
func main() {
type Monster struct {
Name string `json:"name"`
Age int `json:"age"`
Birthday string `json:"birthday"`
Sal float64 `json:"sal"`
Skill string `json:"skill"`
}

monster := Monster{
Name: "张三",
Age: 25,
Birthday: "1997-08-24",
Sal: 800000,
Skill: "太极拳",
}

marshal, err := json.Marshal(monster)
if err != nil {
fmt.Println(err)
}
fmt.Println(string(marshal))
}

// {"name":"张三","age":25,"birthday":"1997-08-24","sal":800000,"skill":"太极拳"}

4、json的反序列化

基本介绍:json反序列化是指将json字符串反序列化成对应的数据类型(比如结构体、map、切片)的操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 应用案例:这里我们介绍一下将json字符串反序列化成结构体、map和切片
package main
import (
"encoding/json"
"fmt"
)

func main() {
type Monster struct {
Name string `json:"name"`
Age int `json:"age"`
Birthday string `json:"birthday"`
Sal float64 `json:"sal"`
Skill string `json:"skill"`
}

// 演示将json字符串,反序列化成struct
// 这里表示str在项目开发中,是通过网络传输获取到,或者读取文件获得的
str := `{"Name":"牛魔王","Age":65,"Birthday":"1500-11-11","Sal":8000,"Skill":"牛魔拳"}`

var monster Monster

err := json.Unmarshal([]byte(str), &monster)

if err != nil {
fmt.Println(err)
}

fmt.Println(monster)
}

// {牛魔王 65 1500-11-11 8000 牛魔拳}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 演示将json字符串反序列化成map
func main() {

str := `{"address":"洪崖洞","age":30,"name":"红孩儿"}`

// 定义一个map
var a map[string]interface{}

// 反序列化
// 注意:反序列化map不需要make,因为make操作被封装到Unmarshal函数中
err := json.Unmarshal([]byte(str), &a)
if err != nil {
fmt.Println(err)
}

fmt.Println(a)
}

// map[address:洪崖洞 age:30 name:红孩儿]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 演示将json字符串,反序列化成切片
func main() {
str := `[{"address":"北京","age":25,"name":"jack"},
{"address":["墨西哥","夏威夷"],"age":20,"name":"tom"}]`

// 定义一个 slice
var slice []map[string]interface{}

// 反序列化,不需要make,因为make操作被封装到Unmarshal函数
err := json.Unmarshal([]byte(str), &slice)
if err != nil {
fmt.Println(err)
}
fmt.Println("反序列化后: ", slice)
}

// [map[address:北京 age:25 name:jack] map[address:[墨西哥 夏威夷] age:20 name:tom]]

代码小结

在反序列化一个json字符串时,要确保反序列化后的数据类型和原来序列化前的数据类型一致
如果json字符串是通过程序获取到的,则不需要对 “” 进行转义处理