目录

一、概述

1、命令行参数

1.1、flag包用来解析命令行参数

2、Json

2.1、Json的序列化

2.2、Json的反序列化

3、单元测试


一、概述

1、命令行参数

os.Args是一个string的切片,用来存储所有的命令行参数
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)}
}
===============================
运行结果如下:
D:\GO_WORKSPACE\src\go_code\project03\day03>go build main.goD:\GO_WORKSPACE\src\go_code\project03\day03>main.exe 1 2 3 4 5
命令行参数有 6
args[0]=main.exe
args[1]=1
args[2]=2
args[3]=3
args[4]=4
args[5]=5
D:\GO_WORKSPACE\src\go_code\project03\day03>

1.1、flag包用来解析命令行参数

带有指定命令行参数形式的命令行,参数位置可以随意

import "flag"
func StringVar(p *string, name string, value string, usage string):
StringVar用指定的名称、默认值、使用信息注册一个string类型flag,并将flag的值保存到p指向的变量。
func IntVar(p *int, name string, value int, usage string):
IntVar用指定的名称、默认值、使用信息注册一个int类型flag,并将flag的值保存到p指向的变量。
=================================================
package main
import ("fmt""flag"
)func main(){var user stringvar pwd stringvar host stringvar port intflag.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\npwd=%v\nhost=%v\nport=%v\n",user,pwd,host,port)
}
==============================
运行结果如下:
D:\GO_WORKSPACE\src\go_code\project03\day03\01>main.exe -u root -pwd 123456 -h 127.0.0.1 -port 3306
user=root
pwd=123456
host=127.0.0.1
port=3306

2、Json

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。

JSON是在2001年开始推广使用的数据格式,目前已经成为主流的数据格式。

JSON易于机器解析和生成,并有效地提升网络传输效率,通常程序在网络传输时先将数据(结构体、map等)序列化成json字符串,到接收方得到json字符串时,在反序列化恢复成原来的数据类型(结构体、map等)。这种方式已然成为各个语言的标准。

在JS语言中,一切都是对象。因此,任何的数据类型都可以通过JSON来表示,例如字符串、数字、对象、数组等。

JSON转换网站验证一个json格式的数据是否正确。

2.1、Json的序列化

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

import "encoding/json"
func Marshal(v interface{}) ([]byte, error):Marshal函数返回v的json编码。
=========================================
package main
import ("fmt""encoding/json"
)
type Monster struct{Name stringAge intSal float64Skill string
}
func structSerial(){monster := Monster{Name :"牛魔王",Age :500,Sal :8000.0,Skill :"牛魔拳",}//将结构体序列化data,err := json.Marshal(&monster)if err != nil {fmt.Printf("序列化错误 err=%v\n",err)}//输出序列化后的结果fmt.Printf("moster序列化后=%v\n",string(data))
}
func main(){structSerial()
}
//moster序列化后={"Name":"牛魔王","Age":500,"Sal":8000,"Skill":"牛魔拳"}

对于结构体的序列化,如果我们希望序列化后的key的名字,由我们自己重新指定,那么可以给结构体指定一个tag标签

type Monster struct{Name string `json:"name"`Age int `json:"age"`Sal float64Skill string
}
//上面的序列化代码改完之后执行结果
//moster序列化后={"name":"牛魔王","age":500,"Sal":8000,"Skill":"牛魔拳"}

2.2、Json的反序列化

json反序列化是指:将json字符串反序列化成对应的数据类型(比如结构体、map、切片)的操作。

import "encoding/json"
func Unmarshal(data []byte, v interface{}) error:Unmarshal函数解析json编码的数据并将结果存入v指向的值。
==================================================
package main
import ("fmt""encoding/json"
)type Monster struct{Name string `json:"name"`Age int `json:"age"`Sal float64Skill string
}func unMarshalStruct(){str :="{\"name\":\"牛魔王\",\"age\":500,\"Sal\":8000,\"Skill\":\"牛魔拳\"}"var monster Monstererr := json.Unmarshal([]byte(str),&monster)if err != nil {fmt.Printf("反序列化错误 err=%v\n",err)}//输出序列化后的结果fmt.Printf("反序列化后 monster=%v\n",monster)
}func main(){unMarshalStruct()unMarshalMap()unMarshalSlice()
}func unMarshalMap(){str := "{\"name\":\"小明\",\"age\":30}"//反序列化时map不需要make,因为make操作被封装到Unmarshal函数中var aMap map[string]interface{}err := json.Unmarshal([]byte(str),&aMap)if err != nil {fmt.Printf("反序列化错误 err=%v\n",err)}//输出序列化后的结果fmt.Printf("反序列化后 aMap=%v\n",aMap)
}func unMarshalSlice(){str := "[{\"name\":\"小明\",\"age\":\"30\"}," +"{\"name\":\"小王\",\"age\":\"31\"}]"var slice []map[string]interface{}err := json.Unmarshal([]byte(str),&slice)if err != nil {fmt.Printf("反序列化错误 err=%v\n",err)}//输出序列化后的结果fmt.Printf("反序列化后 slice=%v\n",slice)
}
  1. 在反序列化一个json字符串,要确保反序列化后的数据类型和原来序列化前的数据类型一致。
  2. 如果json字符串是通过程序获取到的,则不需要再对"转义处理。

3、单元测试

Go语言中自带一个轻量级的测试框架testing和自带的go test命令来实现单元测试和性能测试。

import "testing"
func TestXxx(*testing.T):其中 Xxx 可以是任何字母数字字符串(但第一个字母不能是 [a-z])
func (c *T) Fatalf(format string, args ...interface{}):调用 Fatalf 相当于在调用 Logf 之后调用 FailNow 。
同文件夹下创建2个文件
cal.go文件
package mainfunc Add(n int) int{res := 0for i :=1; i<= n-1;i++{res +=1}return res
}cal_test.go文件
package main
import ("testing"
)func TestAdd(t *testing.T){res:=Add(10)if res != 55 {t.Fatalf("Add(10) 执行错误,期望值=%v 实际值=%v",55,res)}t.Logf("Add(10) 执行正确..")
}
====
执行报错:
D:\GO_WORKSPACE\src\go_code\project03\day05>go test -v
go: go.mod file not found in current directory or any parent directory; see 'go help modules'
解决方案:cmd
go env -w GO111MODULE=auto
==================================
D:\GO_WORKSPACE\src\go_code\project03\day05>go env -w GO111MODULE=autoD:\GO_WORKSPACE\src\go_code\project03\day05>go test -v
=== RUN   TestAddcal_test.go:9: Add(10) 执行错误,期望值=55 实际值=9
--- FAIL: TestAdd (0.00s)
FAIL
exit status 1
FAIL    _/D_/GO_WORKSPACE/src/go_code/project03/day05   0.443sD:\GO_WORKSPACE\src\go_code\project03\day05>
==================================
解释:
GO111MODULE 是 Go 1.11 引入的新版模块管理方式。
GO111MODULE 环境变量用于开启或关闭 Go 语言中的模块支持,它有 off、on、auto 三个可选值,默认为 auto。
GO111MODULE=off
无模块支持,go 会从 $GOPATH 文件夹和 vendor 目录中寻找依赖项。
GO111MODULE=on
模块支持,go 忽略 $GOPATH 文件夹,只根据 go.mod 下载依赖。
GO111MODULE=auto
在 $GOPATH/src 外层且根目录有 go.mod 文件时,开启模块支持;否者无模块支持。
testing框架原理
将xxx_test.go的文件引入  import ...
main(){//2.调用TestXxx()函数
}
  1. 测试用例文件名必须以_test.go结尾
  2. 测试用例函数必须以Test开头
  3. TestXxx(t testing.T)的形参类型必须是testing.T
  4. 一个测试用例文件中,可以有多个测试用例函数
  5. 运行测试用例指令
    1. cmd>go test [如果运行正确,无日志,错误时,会输出日志]
    2. cmd>go test -v [运行正确或错误,都输出日志]
  6. 当出现错误时,可以使用t.Fatalf来格式化输出错误信息,并退出程序
  7. t.Logf方法可以输出相应的日志
  8. 测试用例函数,并没有放在main函数中,也执行了,这就是测试用例的方便之处
  9. PASS表示测试用例运行成功,FAIL表示测试用例运行失败
  10. 测试单个文件,一定要带上被测试的原文件
cmd>go test -v cal_test.go cal.go
  1. 测试单个方法
cmd>go test -v -test.run TestAdd

干我们这行,啥时候懈怠,就意味着长进的停止,长进的停止就意味着被淘汰,只能往前冲,直到凤凰涅槃的一天!