1.源码文件分类


环境变量GOPATH指向的是一个或多个工作区,而且每个工作区都会有以代码包为基本组织形式的源码文件。

源码文件分为三种,即:命令源码文件、库源码文件和测试源码文件。


2.什么是命令源码文件,它有什么用途,怎样编写它


命令源码文件是程序的运行入口,是每个可读库运行的程序必须拥有的。如果一个源码文件声明属于main包,并且包含一个无参数声明且无结果声明的main函数,那么就是命令源码文件。

当需要模块化编程时,我们会将代码拆分到多个文件下,不同的代码包中。但无论怎样,对于一个独立的程序来说命令源码文件永远只会也只能有一个。如果有与命令源码文件同包的源码文件,那么他们也应该声明属于main包。


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

go语言标准库中有一个代码包专门用于接收和解析命令参数。这个代码包的名字叫做flag。下面根据例子来进行讲解。

例子:

package main

import (
"flag" //导入所需的flag包
"fmt"
)

var name string

func init() {

flag.StringVar(&name, "name", "every one", "to say hello")//初始化flag,第一个参数用于储存该命令参数的值的地址,第二个参数是为了指定命令参数名称,第三个参数是为使用参数时的默认值,第四个参数为说明参数。

此处还可以改为var name = flag.String("name","everyone","the greeting object")
}
func main() {
flag.Parse()//解析命令参数
fmt.Println("hello world " + name)
}


4.怎样在运行命令源码文件时传入参数,以及怎样查看参数使用说明


运行如下命令传入参数:

go run test.go -name="Robert"

运行结果:

Hello world Robert

查看命令源码文件的参数说明 go run test.go --help

结果:

Usage of C:\Users\nshu\AppData\Local\Temp\go build740295486\b001\exe\test.exe:
-name string
to say hello (default "every one")
exit status 2

第一行为go run临时生成的可执行文件的完整路径。


5.怎样自定义命令源码文件的参数使用说明

自定义命令源码文件的参数使用说明有很多方法,在这举几个例子:


1.对变量flag.Usage重新赋值,该变量在声明flag时就已经被赋值了,在这里可以对它重新赋值。对flag.Usage的赋值必须在调用flag.Parse函数之前

例子:

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


再输入go run test.go --help之后输出:

Usage of question:
-name string
to say hello (default "every one")
exit status 2


2.当我们在调用flag包中的一些函数(例如StringVar)的时候,实际上在调用flag.CommandLine变量的对应方法,这时我们可以通过以下方法来定义参数使用说明:

func init() {
flag.CommandLine= flag.NewFlagSet("", flag.ExitOnError)
flag.CommandLine.Usage = func() {
fmt.Printf("Usage of %s:\n", "question")
flag.PrintDefaults()
}
flag.StringVar(&name, "name", "every one", "to say hello")
}

此时将flag.ExitOnError改为flag.PanicOnError此时就会产生另一种输出效果。这两个参数都是flag包中的常量。

flag.ExitOnError的含义是,告诉命令参数容器,当命令后跟--help或者参数不正确时,打印命令参数使用说明后以状态码2结束当前程序。

flag.PanicOnError与之的区别是在最后跑出“运行时错误”


3.我们还可以自己创建一个私有的命令参数容器来代替flag.CommandLine

例子:

package main

import (
"flag"
"fmt"
"os"
)

var name string
var nshu = flag.NewFlagSet("", flag.PanicOnError)

func init() {
nshu.Usage = func() {
fmt.Printf("Usage of %s:\n", "question")
nshu.PrintDefaults()
}
nshu.StringVar(&name, "name", "every one", "to say hello")
}
func main() {
// flag.Usage = func() {
// fmt.Printf("Usage of %s:\n", "question")
// flag.PrintDefaults()
// }
nshu.Parse(os.Args[1:]) //与之前flag下的Parse不一样
fmt.Println("hello world " + name)
}

这种定制并不会影响全局变量flag.CommandLine