Go基础2 程序的运行入口 - 命令源码文件

103 阅读2分钟
程序的运行入口 - 命令源码文件

命令源码文件是程序的运行入口,是每个可独立运行的程序必须拥有的。我们可以通过构建或安装,生成与其对应的可执行文件,后者一般会与该命令源码文件的直接父目录同名。

特点:

  1. 如果一个源码文件声明属于main包,并且包含一个无参数声明且无结果声明的main函数,那么它就是命令源码文件。
  2. 对于一个独立的程序来说,命令源码文件永远只会也只能有一个。如果有与命令源码文件同包的源码文件,那么它们也应该声明属于main包。

命令源码的编写技巧

1. 命令源码文件怎样接收参数

Go提供了flag库来进行参数的传递与接收:

flag.StringVar(&name, "name", "everyone", "The greeting object.")

第 1 个参数是用于存储该命令参数值的地址,具体到这里就是在前面声明的变量name的地址了,由表达式&name表示。
第 2 个参数是为了指定该命令参数的名称,这里是name。
第 3 个参数是为了指定在未追加该命令参数时的默认值,这里是everyone。
第 4 个函数参数,即是该命令参数的简短说明了,这在打印命令说明时会用到。

flag.Parse()

2. 怎样在运行命令源码文件的时候传入参数,又怎样查看参数的使用说明\

go run xx.go -name="xx"

PS D:\Terry\GoSync\src\name_code> go run .\entrance.go -name="Terry"
Hello, Terry!

go run xx.go --help

PS D:\Terry\GoSync\src\name_code> go run .\entrance.go --help       
Usage of C:\Users\Aylee\AppData\Local\Temp\go-build358867118\b001\exe\entrance.exe:
  -name string
        The greeting object. (default "everyone")

3. 怎样自定义命令源码文件的参数使用说明 我们可以通过覆盖flag.Usage的值来修改使用说明,该操作要在flag.Parse()之前。

比如,我们可以在main函数的首部加上如下代码:

flag.Usage = func() {
 fmt.Fprintf(os.Stderr, "Usage of %s:\n", "question")
 flag.PrintDefaults()
}

4. 如何通过CommandLine深度定制 我们在调用flag包中的一些函数(比如StringVar、Parse等等)的时候,实际上是在调用flag.CommandLine变量的对应方法。所以我们也可以直接覆盖CommandLine.Usage来实现修改。

flag.CommandLine = flag.NewFlagSet("", flag.PanicOnError) #在最后抛出“运行时恐慌(panic)
flag.CommandLine = flag.NewFlagSet("", flag.ExitOnError)#告诉命令参数容器,当命令后跟--help或者参数设置的不正确的时候,在打印命令参数使用说明后以状态码2结束当前程序
flag.CommandLine.Usage = func() {
 fmt.Fprintf(os.Stderr, "Usage of %s:\n", "question")
 flag.PrintDefaults()
}

自定义cmdline
我们也可以通过flag.NewFlagSet来自定义一个参数命令容器。

var cmdLine = flag.NewFlagSet("question", flag.ExitOnError)#创建一个私有参数命令容器
cmdLine.StringVar(&name, "name", "everyone", "The greeting object.")
cmdLine.Parse(os.Args[1:])

例子

package main

import (
   "flag"
   "fmt"
)

var name string
#var name = flag.String("name", "everyone", "The greeting object.")


func init() {
   flag.StringVar(&name, "name", "everyone", "The greeting object.")
}

func main() {
   flag.Parse()
   fmt.Printf("Hello, %s!\n", name)
}