命令行参数 && 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"}
View Code

 

 

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 ~

 

posted @ 2019-07-21 23:43  kaichenkai  阅读(610)  评论(0编辑  收藏  举报