Golang学习+深入(十二)-命令行参数/Json/单元测试

目录

一、概述

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.go

D:\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 string
	var pwd string
	var host string
	var port int

	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\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 string
	Age int
	Sal float64
	Skill 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 float64
	Skill 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 float64
	Skill string
}

func unMarshalStruct(){
	str :="{\"name\":\"牛魔王\",\"age\":500,\"Sal\":8000,\"Skill\":\"牛魔拳\"}"
	var monster Monster
	err := 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 main

func Add(n int) int{
	res := 0
	for 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=auto

D:\GO_WORKSPACE\src\go_code\project03\day05>go test -v
=== RUN   TestAdd
    cal_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.443s

D:\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

Golang学习+深入(十三)-goroutine/channal

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杀神lwz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值