此为 《极客时间&Go语言核心36讲》 个人笔记,具体课程详见极客时间官网。
Table of Contents generated with DocToc
- 第二讲 命令源码文件
- 1. 什么是命令源码文件?
- 2. 命令参数的接收和解析
- 2.1 命令源码文件怎么接收参数?
- 2.2 怎样在运行源代码文件的时候传入参数,又怎样查看参数的使用说明?
- 3. 补充
- 3.1 问题
- 3.2 其他
第二讲 命令源码文件
源码文件分为三种:
- 命令源码文件
- 库源码文件
- 测试源码文件
1. 什么是命令源码文件?
如果一个源码文件声明属于main
包,并且包含一个无参数声明且无结果声明的main
函数,那么它就是命令源码文件。
命令源码文件是程序的运行入口,是每个可独立运行的程序必须拥有的,有且只有一个。
2. 命令参数的接收和解析
2.1 命令源码文件怎么接收参数?
Go
语言标准库中有一个代码包专门用于接收和解析命令参数——flag
。
// func StringVar(p *string, name string, value string, usage string) {}
var name string
flag.StringVar(&name, "name", "zcz", "my name is ... ?")
flag.Parse()
fmt.Println(name)
参数说明:
- p :用于存储该命令参数的值的地址;
- name:参数名称;
- value:默认值;
- usage:该命令参数的简单描述,在打印命令说明时会用到;
flag.Parse()
解析命令参数并把它们的值付给相应的变量。对该函数的调用必须在所有命令参数存储载体的声明(如上name
的声明)和设置(如上flag.StringVar()
的调用)之后,并且在读取任何命令参数值之前进行。
除了flag.StringVar()外,还有一个flag.String()方法,它会返回一个指向存储命令参数的地址:
// func String(name string, value string, usage string) *string {}
name := flag.String("name", "zcz", "my name is ... ?")
flag.Parse()
fmt.Println(name)
2.2 怎样在运行源代码文件的时候传入参数,又怎样查看参数的使用说明?
传参方式如下:
go run parameter.go -name="xxt"
//output: xxt
查看该命令源码文件的参数说明:
go run parameter.go --help
/* output:Usage of /var/folders/n2/m16dmxhn2mld82h_6ywcc14h0000gn/T/go-build1423020904/b001/exe/parameter:-name stringmy name is ... ? (default "zcz")
*/
其中,/var/folders/n2/m16dmxhn2mld82h_6ywcc14h0000gn/T/go-build1423020904/b001/exe/parameter
是go run
命令构建上述命令源码文件时临时生成的可执行文件的完整路径。
我们还可以:
go build parameter.go
./parameter.go --help
/* output:Usage of ./parameter:-name stringmy name is ... ? (default "zcz")
*/
3. 补充
3.1 问题
var name string
flag.StringVar(&name, "name1", "zcz01", "my name is ... ?")
flag.StringVar(&name, "name2", "zcz02", "wtf ?")
flag.Parse()
fmt.Println(name)
- 执行
go run parameter.go -name1="kodo" -name2="pili"
,输出为:pili
; - 执行
go run parameter.go -name2="pili" -name1="kodo"
,输出为:kodo
; - 执行
go run parameter.go -name1="kodo"
,输出为:kodo
; - 执行
go run parameter.go -name2="pili"
,输出为:pili
;
why?(后续解决)
3.2 其他
-
默认情况下,我们可以让命令源码文件接受哪些类型的参数值?
int ( int | int64 | uint | uint64 ) ,
float ( float | float64 ) ,
string ,
bool ,
duration ( 时间 ) ,
var ( 自定义 ) -
我们可以把自定义的数据类型作为参数值的类型吗?如果可以,怎样做?
关键就是使用flag.var(),关键点在于需要实现flag包的Value接口。(后续会展开)