<>

作者: 凹大猫的鱼 | 来源:发表于2018-09-29 14:50 被阅读0次

    第二章重点:

    Go 的源码文件分类:

    在第一章的时候已经提及到了这个关键问题:

    (1)命令源码文件:
        声明自己属于 main 代码包、包含无参数声明和结果声明的 main 函数。
        命令源码文件被安装以后,GOPATH 如果只有一个工作区,那么相应的
        可执行文件会被存放当前工作区的 bin 文件夹下;如果有多个工作区,
        就会安装到 GOBIN 指向的目录下。
    
    (2)库源码文件
        
        库源码文件就是不具备命令源码文件上述两个特征的源码文件。存在于某个代码包中的普通的源码文件。
    
    (3)测试源码文件
    
        名称以 _test.go 为后缀的代码文件,并且必须包含 Test 或者 Benchmark 名称前缀的函数。
    

    GO语言的flag包:

    微课堂主要介绍了一下flag包的用法。并且付上了官方文档。所以在这里稍微列举一下用法。

    flag的定义:

    flag.String(), Bool(), Int() //这里这是列举了几个
    

    然后就是两种定义的方式:

    var ip = flag.Int("flagname", 1234, "help message for flagname") //ip 为指针类型,Int或者
    String返回的都是指针类型
    
    flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")//此处需要在外面手动定义flagvar
    

    第一种方式是返回一个值,第二种方式是把变量的传进去。

    通过flag.Var()绑定自定义类型,自定义类型需要实现Value接口(Receives必须为指针),如:

    flag.Var(&flagVal, "name", "help message for flagname")
    

    对于这种类型的flag,默认值为该变量类型的初始值

    flag的解析

    flag.Parse()
    

    解析函数将会在碰到第一个非flag命令行参数时停止,非flag命令行参数是指不满足命令行语法的参数,如命令行参数为cmd --flag=true abc则第一个非flag命令行参数为“abc”

    flag解析后的参数使用

    fmt.Println("ip has value ", *ip)
    fmt.Println("flagvar has value ", flagvar)
    

    命令行语法

    -flag //只支持bool类型
    -flag=x
    -flag x //只支持非bool类型
    

    注意第三种只支持非bool类型,原因就是如果文件的名字为false的话那么就会产生歧义。看例子:

    package main
    
    import (
        "flag"
        "fmt"
    )
    
    var name string
    var right bool
    func init() {
        flag.StringVar(&name, "name", "everyone", "The greeting object.")
        flag.BoolVar(&right, "check", false, "The right ob")
    }
    
    func main() {
        flag.Parse()
        Hello(name)
        fmt.Println(right)
    }
    
    这里采用的还是老师的例子,只多加了个bool类型。
    我们编译之后生成exe
    
    demo4.exe -check false
    demo4.exe -check
    
    对于这两种都会采用默认的bool类型true。
    
    demo4.exe -check=false
    
    只有这样的时候,才会采用false
    

    定义自己的参数使用说明

    第一种:
    
    最简单就是修改Usages这个函数变量:
    
    var Usage = func() {
        fmt.Fprintf(CommandLine.Output(), "Usage of %s:\n", os.Args[0])
        PrintDefaults()
    }
    
    我们可以看一下源码里面采用的是第一个参数的名字也就是我们的exe文件。
    
    var Usage = func() {
        fmt.Fprintf(CommandLine.Output(), "HaoLin guid%s:\n", "wenxuwan")
        PrintDefaults()
    }
    这样你就可以定义输出了
    
    郝林老师还讲了更深入的定义自己的类型。主要是更深入的定义flag包里面的一些对象实现自己的方法,具体可以看下源码。
    

    思考题

    1. 默认情况下,我们可以让命令源码文件接受哪些类型的参数值?
    这个从flag包的代码包里面就可以看到,这里贴一下班里一个同学的答案
    
        int(int|int64|uint|uint64),
        float(float|float64)
        string,
        bool,
        duration(时间),
        var(自定义)
    
    
    2. 我们可以把自定义的数据类型作为参数值的类型吗?如果可以,怎样做?
    
        当然是可以的:
        // Var defines a flag with the specified name and usage string. The type and
        // value of the flag are represented by the first argument, of type Value, which
        // typically holds a user-defined implementation of Value. For instance, the
        // caller could create a flag that turns a comma-separated string into a slice
        // of strings by giving the slice the methods of Value; in particular, Set would
        // decompose the comma-separated string into the slice.
        func Var(value Value, name string, usage string) {
            CommandLine.Var(value, name, usage)
        }
    
        type pepoInfo struct{
            name string
            age int
            homeAdress string
        }
    
        func (p * pepoInfo) Set(val string) error{
            peopleList := strings.Split(val, ",")
            p.name = peopleList[0]
            p.age,_ =  strconv.Atoi(peopleList[1])
            p.homeAdress = peopleList[2]
            return nil
        }   
    
        func (s *pepoInfo) String() string {
            infoList := strings.Split("wenxuwan,20,山东", ",")
            s.name = infoList[0]
            s.age,_ = strconv.Atoi(infoList[1])
            s.homeAdress = infoList[2]
            return "It's none of my business"
        }
        func main(){
    
        var people pepoInfo
        flag.Var(&people, "info", "hao ma fan")
        flag.Parse()
        //打印结果slice接收到的值
        fmt.Println(people)
        }
    
    demo4.exe --info wenxuwan,10,shouguang
    

    相关文章

      网友评论

          本文标题:<>

          本文链接:https://www.haomeiwen.com/subject/yqtboftx.html