Files
the-way-to-go_ZH_CN/eBook/12.4.md
2015-09-25 00:27:05 +08:00

4.0 KiB
Raw Blame History

从命令行读取参数

12.4.1 os包

os包中有一个string类型的切片变量os.Args,其用来处理一些基本的命令行参数,它在程序启动后读取命令行输入的参数。来看下面的打招呼程序:

示例 12.11 os_args.go

// os_args.go
package main

import (
	"fmt"
	"os"
	"strings"
)

func main() {
	who := "Alice "
	if len(os.Args) > 1 {
		who += strings.Join(os.Args[1:], " ")
	}
	fmt.Println("Good Morning", who)
}

我们在IDE或编辑器中直接运行这个程序输出Good Morning Alice

我们在命令行运行os_args or ./os_args会得到同样的结果。

但是我们在命令行加入参数,像这样:os_args John Bill Marc Luke,将得到这样的输出:Good Morning Alice John Bill Marc Luke

这个命令行参数会放置在切片os.Args[]以空格分隔从索引1开始os.Args[0]放的是程序本身的名字,在本例中是os_args)。函数strings.Join函数用来连接这些参数,以空格作为间隔。

练习 12.5hello_who.go 写一个"Hello World"的变种程序:把人的名字作为程序命令行执行的一个参数,比如: hello_who Evan Michael Laura 那么会输出Hello Evan Michael Laura!

12.4.2 flag包

flag包有一个扩展功能用来解析命令行选项。但是通常被用来替换基本常量例如在某些情况下我们希望在命令行给常量一些不一样的值。参看19章的项目

在flag包中一个Flag被定义成一个含有如下字段的结构体

type Flag struct {
	Name     string // name as it appears on command line
	Usage    string // help message
	Value    Value  // value as set
	DefValue string // default value (as text); for usage message
}

下面的程序echo.go模拟了Unix的echo功能

package main

import (
	"flag" // command line option parser
	"os"
)

var NewLine = flag.Bool("n", false, "print newline") // echo -n flag, of type *bool

const (
	Space   = " "
	Newline = "\n"
)

func main() {
	flag.PrintDefaults()
	flag.Parse() // Scans the arg list and sets up flags
	var s string = ""
	for i := 0; i < flag.NArg(); i++ {
		if i > 0 {
			s += " "
			if *NewLine { // -n is parsed, flag becomes true
				s += Newline
			}
		}
		s += flag.Arg(i)
	}
	os.Stdout.WriteString(s)
}

flat.Parse()扫描参数列表或者常量列表并设置flag, flag.Arg(i)表示第i个参数。Parse()之后所有flag.Arg(i)全部可用,flag.Arg(0)就是第一个真实的flag而不是像os.Args(o)放置程序的名字。

flag.Narg()返回参数的数量。解析后flag或常量就可用了。flag.Bool()定义了一个默认值是false的flag当在命令行出现了第一个参数这里是"n"flag被设置成'true'NewLine是*bool类型)。如果*NewLine表示对flag解引用所以当值是true时将添加一个newline。

flag.PrintDefaults()打印flag的使用帮助信息本例中打印的是

	-n=false: print newline

flag.VisitAll(fn func(*Flag))是另一个有用的功能按照字典顺序遍历flag并且对每个标签调用fn(参考15.8章的例子)

当在命令行Windows中执行echo.exe A B C,将输出:A B C;执行echo.exe -n A B C,将输出:

A
B
C

每个字符的输出都新起一行,每次都在输出的数据前面打印使用帮助信息:-n=false: print newline

对于flag.Bool你可以设置布尔型flag来测试你的代码例如定义一个flag processedFlag:

	var processedFlag = flag.Bool(proc, false, nothing processed yet)

在后面用如下代码来测试:

	if *processedFlag { // found flag -proc
		r = process()
	}

要给flag定义其它类型可以使用flag.Int()flag.Float64flag.String()

在15.8章你将找到一个完成的例子。

链接