这里介绍的是每个工作区中,以代码包为基本组织形式的源码文件。
源码文件分三种:命令源码文件、库源码文件、测试源码文件。三者有不同的用途和编写规则。
命令源码文件:
what:命令源码文件是程序的运行入口,是每个可独立运行的程序必须拥有的。我们可以通过构建或安装,生成与其对应的可执行文件,后者一般会与该命令源码文件的直接父目录同名。
how:如果一个源码文件声明属于main包,并且包含一个无参数声明且无结果声明的main函数,那么它就是命令源码文件。
举个栗子:就像下面这段代码
package main
import "fmt"
func main() {
fmt.Println("Hello, world!")
}
如果你把这段代码存成 demo1.go 文件,那么运行go run demo1.go命令后就会在屏幕(标准输出)中看到Hello, world!。
模块化编程时,往往会将代码拆分到多个文件,甚至拆分到不同的代码包中。但对于一个独立的程序来说,命令源码文件永远只会也只能有一个。如果有与命令源码文件同包的源码文件,那么它们也应该声明属于
main包。
命令参数的接收和解析:几乎所有命令(command)都是可以接收参数(argument)的。
what(命令):通过构建或安装命令源码文件,生成的可执行文件就可以被视为“命令”,既然是命令,那么就应该具备接收参数的能力。无论是 Linux 还是 Windows,如果你用过命令行(command line)的话,肯定就会知道几乎所有命令(command)都是可以接收参数(argument)的。
命令源码文件怎么接收参数
看一段代码
package main
import (
// 需在此处添加代码。[1]
"flag"
"fmt"
)
var name string
func init() {//这个init函数不必在main中调用,在这里定义好就行
// 需在此处添加代码。[2]
flag.StringVar(&name, "name", "everything", "The greeting object")
}
func main() {
// 需在此处添加代码。[3]
flag.Parse()
fmt.Printf("Hello, %s!\n", name)
}
Go 语言标准库中有一个代码包专门用于接收和解析命令参数。这个代码包的名字叫flag。
flag.StringVar(&name, "name", "everyone", "The greeting object.")
参数1:上面声明过的变量的地址,用于存储该命令参数值
参数2:用于指定参数的名称
参数3:默认参数
参数4:打印命令说明
关于flag.StringVar与flag.String的区别: 后者返回一个分配好地址的参数实体
关于函数flag.Parsewhat: 用于真正解析命令参数,并把它们的值赋给相应的变量。
how: 对该函数的调用必须在所有命令参数存储载体的声明(这里是对变量name的声明)和设置(这里是在[2]处对flag.StringVar函数的调用)之后,并且在读取任何命令参数值之前进行。正因为如此,我们最好把flag.Parse()放在main函数的函数体的第一行。
怎样在命令源码文件执行的时候传参,怎样查看参数的使用说明
两个问题,执行的时候怎么传参&怎么查看参数声明
举个栗子(关于传参)
输入命令,
go run test.go -name="STY", 结果Hello, STY!
举个栗子(关于查看参数声明)
输入命令,
go run test.go --help
返回结果是:Usage of C:\Users\90682\AppData\Local\Temp\go-build600599929\b001\exe\test.exe: -name string The greeting object (default "everything")这其实是
go run命令构建上述命令源码文件时临时生成的可执行文件的完整路径。
如果我们先构建这个命令源码文件再运行生成的可执行文件>go build test.go A:\goWorkAreas\src\test>test --help Usage of test: -name string The greeting object (default "everything")
怎样自定义命令源码文件的参数使用说明(即对参数使用说明更为详细的定制化)
略
总结
可以用 Go 编写命令,并可以让它们像众多操作系统命令那样被使用,甚至可以把它们嵌入到各种脚本中。
思考题
- 默认情况下,我们可以让命令源码文件接受哪些类型的参数值?
这个问题查看flag库文件中的具体函数类型就可以flag.IntVar/flag.BoolVar/flag.StringVar...
- 我们可以把自定义的数据类型作为参数值的类型吗?如果可以,怎样做?(怎样声明自己的数据类型)