zoukankan      html  css  js  c++  java
  • 命令行参数 && 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:UserschenkaiAppDataLocalTemp\___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	%v	%v	", 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	%v	%v	
    ", mode, level, onOff)
    	fmt.Printf("%v	%v	%v	", *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 ~

    每天都要遇到更好的自己.
  • 相关阅读:
    hash_map和map的区别
    STL中map与hash_map容器的选择收藏
    ServletContextListener和ContextLoaderListener的区别
    解决Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:compile
    详解Tomcat线程池原理及参数释义
    Tomcat使用线程池配置高并发连接
    详解 Tomcat 的连接数与线程池
    ServletContextListener接口用法
    Spring Quartz定时任务如何获得ServletContext对象?
    如何在spring quartz类中拿到ServletContext
  • 原文地址:https://www.cnblogs.com/kaichenkai/p/11223439.html
Copyright © 2011-2022 走看看