命令行参数 && json 协议 && 自定义 error 类型
命令行参数
在写代码的时候,在运行程序做一些初始化操作的时候,往往会通过命令行传参数到程序中,那么就会用到命令行参数
例如,指定程序运行的模式和级别:
go run HTTPServer.go --mode survival --level 1
os.Args
可以通过 os 包的 Args 变量来获取所有命令行参数,得到的是一个 string 切片类型([]string),第一个命令行参数就是执行文件本身
package main import ( "fmt" "os" ) func main (){ fmt.Println(os.Args) } 运行结果: [C:\Users\chenkai\AppData\Local\Temp\___go_build_main_go__3_.exe]
flag 包
使用 flag 包解析命令行参数的方法有两类,下面记录一下用法
1)对已初始化的变量进行赋值(推荐使用)
package main import ( "flag" "fmt" ) func main (){ var mode string var level int var onOff bool flag.StringVar(&mode,"mode", "survival", "game pattern") flag.IntVar(&level, "level", 1, "game level") flag.BoolVar(&onOff, "onOff", true, "game onOff") //解析命令行参数 flag.Parse() fmt.Printf("%v\t%v\t%v\t", mode, level, onOff) } 运行结果: survival 0 true
2)使用指针变量接收
package main import ( "flag" "fmt" ) func main (){ var mode *string = flag.String("mode", "survival", "game pattern") var level *int = flag.Int("level", 1, "game level") var onOff *bool = flag.Bool("onOff", true, "game onOff") //解析命令行参数 flag.Parse() fmt.Printf("%v\t%v\t%v\t\n", mode, level, onOff) fmt.Printf("%v\t%v\t%v\t", *mode, *level, *onOff) } 运行结果: 0xc00004e200 0xc0000620c0 0xc0000620c8 survival 0 true
json 协议
json 是跨平台的一种数据格式,当然,Go 也是支持 json 协议的,分为 json 序列化 和 反序列化
- 序列化:将 Go 中的数据类型转换成 json 格式的字符串
- 反序列化:将 json 字符串作用于 Go 中的数据类型上
1)序列化(json.Marshal)
结构体转 json:
package main import ( "encoding/json" "fmt" ) type User struct { UserName string NickName string Age int Sex string Email string } func main (){ var userA User = User{ UserName: "托尼", NickName: "tony", Age: 36, Sex: "男", Email: "tony@163.com", } var jsonData []byte //func Marshal(v interface{}) ([]byte, error) jsonData, err := json.Marshal(userA) if err != nil { fmt.Printf("json marshal error[%v]", err) } fmt.Println(string(jsonData)) } 运行结果: {"UserName":"托尼","NickName":"tony","Age":36,"Sex":"男","Email":"tony@163.com"}
如果想要更改 json 字符串的 key,可以设置结构体 json 标签:
package main import ( "encoding/json" "fmt" ) type User struct { UserName string `json:"username"` NickName string `json:"nickname"` Age int `json:"age"` Sex string `json:"sex"` Email string `json:"email"` } func main (){ var userA User = User{ UserName: "托尼", NickName: "tony", Age: 36, Sex: "男", Email: "tony@163.com", } var jsonData []byte //func Marshal(v interface{}) ([]byte, error) jsonData, err := json.Marshal(userA) if err != nil { fmt.Printf("json marshal error[%v]", err) } fmt.Println(string(jsonData)) } 运行结果: {"username":"托尼","nickname":"tony","age":36,"sex":"男","email":"tony@163.com"}
map 转 json:
package main import ( "encoding/json" "fmt" ) func main (){ var mapA map[string]string = make(map[string]string) mapA["name"] = "johny" mapA["email"] = "johny@163.com" var jsonData []byte jsonData, err := json.Marshal(mapA) if err != nil { fmt.Printf("json marshal error[%v]", err) } fmt.Println(string(jsonData)) } 运行结果: {"email":"johny@163.com","name":"johny"}
2)反序列化(json.Unmarshal)
json 返序列化为结构体:先获取一个结构体的 json 数据,然后赋值给另一个 结构体类型
package main import ( "encoding/json" "fmt" ) type User struct { UserName string `json:"username"` NickName string `json:"nickname"` Age int `json:"age"` Sex string `json:"sex"` Email string `json:"email"` } func marshalData() string { var userA User = User{ UserName: "托尼", NickName: "tony", Age: 36, Sex: "男", Email: "tony@163.com", } var jsonData []byte //func Marshal(v interface{}) ([]byte, error) jsonData, err := json.Marshal(userA) if err != nil { fmt.Printf("json marshal error[%v]", err) } return string(jsonData) } func main (){ jsonData := marshalData() var userB User = User{} fmt.Println(userB) //func Unmarshal(data []byte, v interface{}) error err := json.Unmarshal([]byte(jsonData), &userB) if err != nil { fmt.Printf("json unmarshal error[%v]", err) } fmt.Println(userB) } 运行结果: { 0 } //空白部分是空字符串,string 类型默认值是空字符串,int 类型默认值是 0 {托尼 tony 36 男 tony@163.com}
自定义 error
自定义错误内容一般用的很少,不过也需要了解一下,主要是实现一个 Error() 方法,成为 error 接口类型即可实现自定义的错误类型
实现了 error 接口,就是 error 类型,error 接口定义如下:
type error interface { Error() string }
demo:打开文件错误时,返回自定义的错误内容
package main import ( "encoding/json" "fmt" "os" "time" ) type OpenError struct { Path string Operation string CreateTime time.Time Message string } func (openErr OpenError) Error() string { var jsonData []byte jsonData, err := json.Marshal(openErr) if err != nil { fmt.Printf("json marshal error[%v]", err) } return string(jsonData) } func openFile(filepath string) error { file, err := os.Open(filepath) if err != nil { var openErr OpenError = OpenError{ Path: filepath, Operation:"read", CreateTime: time.Now(), Message: err.Error(), } return openErr } defer file.Close() return nil } func main(){ //err := openFile("D:\\golang_workspace\\file_test\\source.txt") err := openFile("D:\\golang_workspace\\file_testsdafs") if err != nil { fmt.Println(err.Error()) } } 运行结果: {"Path":"D:\\golang_workspace\\file_testsdafs","Operation":"read","CreateTime":"2019-07-23T22:50:31.7511949+08:00","Message":"open D:\\golang_workspace\\file_testsdafs: The system cannot find the file specified."}
ending ~
每天都要遇到更好的自己.