golang学习笔记 ---命令行参数

时间:2022-07-02 03:31:19

os 包以跨平台的方式,提供了一些与操作系统交互的函数和变量。程序的命令行参数可从os
包的Args变量获取;os包外部使用os.Args访问该变量。

os.Args变量是一个字符串(string)的切片(slice)(译注:slice和Python语言中的切片类
似,是一个简版的动态数组),切片是Go语言的基础概念,稍后详细介绍。现在先把切片s当
作数组元素序列, 序列的成长度动态变化, 用 s[i] 访问单个元素,用 s[m:n] 获取子序列(译
注:和python里的语法差不多)。序列的元素数目为len(s)。和大多数编程语言类似,区间索引
时,Go言里也采用左闭右开形式, 即,区间包括第一个索引元素,不包括最后一个, 因为这样
可以简化逻辑。(译注:比如a = [1, 2, 3, 4, 5], a[0:3] = [1, 2, 3],不包含最后一个元素)。比
如s[m:n]这个切片,0 ≤ m ≤ n ≤ len(s),包含n-m个元素。

os.Args的第一个元素,os.Args[0], 是命令本身的名字;其它的元素则是程序启动时传给它的
参数。s[m:n]形式的切片表达式,产生从第m个元素到第n-1个元素的切片

程序用到的参数包含在os.Args[1:len(os.Args)]切片中

示例:

package main

import (
	"fmt"
	"os"
)

func main() {
	var s, sep string
	for i := 1; i < len(os.Args); i++ {
		s += sep + os.Args[i]
		sep = " "
	}
	fmt.Println(s)
}

  

自增语句 i++ 给 i 加1;这和 i += 1 以及 i = i + 1 都是等价的。对应的还有 i-- 给 i 减
1。它们是语句。而不像C系的其它语言那样是表达式。所以 j = i++ 非法,而且++和--都只能放在变量名后面,因此 --i 也非法。

Go语言只有for循环这一种循环语句。for循环有多种形式,其中一种如下所示:
for initialization; condition; post {
// zero or more statements
}

for循环三个部分不需括号包围。大括号强制要求, 左大括号必须和post语句在同一行。

initialization语句是可选的,在循环开始前执行。initalization如果存在,必须是一条简单语句
(simple statement),即,短变量声明、自增语句、赋值语句或函数调用。 condition 是一
个布尔表达式(boolean expression),其值在每次循环迭代开始时计算。如果为 true 则执
行循环体语句。 post 语句在循环体执行结束后执行,之后再次对 conditon 求
值。 condition 值为 false 时,循环结束。

for循环的这三个部分每个都可以省略,如果省略 initialization 和 post ,分号也可以省
略:
// a traditional "while" loop
for condition {
// ...

如果连 condition 也省略了,像下面这样:
// a traditional infinite loop
for {
// ...
}

这就变成一个无限循环,尽管如此,还可以用其他方式终止循环, 如一条 break 或 return 语
句。

for 循环的另一种形式, 在某种数据类型的区间(range)上遍历,如字符串或切
片。

package main
import (
"fmt"
"os"
)
func main() {
	s, sep := "", ""
	for _, arg := range os.Args[1:] {
		s += sep + arg
		sep = " "
	}
	fmt.Println(s)
}

每次循环迭代字符串s的内容都会更新。 += 连接原字符串、空格和下个参数,
产生新字符串, 并把它赋值给 s 。 s 原来的内容已经不再使用,将在适当时机对它进行垃圾
回收。

如果连接涉及的数据量很大,这种方式代价高昂。一种简单且高效的解决方案是使
用 strings 包的 Join 函数

每次循环迭代, range 产生一对值;索引以及在该索引处的元素值。这个例子不需要索引,
但 range 的语法要求, 要处理元素, 必须处理索引。一种思路是把索引赋值给一个临时变量,
如 temp , 然后忽略它的值,但Go语言不允许使用无用的局部变量(local variables),因为这
会导致编译错误。

Go语言中这种情况的解决方法是用 空标识符 (blank identifier),即 _ (也就是下划线)。
空标识符可用于任何语法需要变量名但程序逻辑不需要的时候, 例如, 在循环里,丢弃不需要
的循环索引, 保留元素值。

声明一个变量有好几种方式,下面这些都等价:

s := ""
var s string
var s = ""
var s string = "" 

第一种形式,是一条短变量声明,最简洁,但只能用在函数内
部,而不能用于包变量。

第二种形式依赖于字符串的默认初始化零值机制,被初始化为""。

第三种形式用得很少,除非同时声明多个变量。第四种形式显式地标明变量的类型,当变量类

型与初值类型相同时,类型冗余,但如果两者类型不同,变量类型就必须了。实践中一般使
用前两种形式中的某个,初始值重要的话就显式地指定变量的类型,否则使用隐式初始化。

 

用 strings 包的 Join 函数:

package main

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

func main() {
	fmt.Println(strings.Join(os.Args[1:], " "))

}

如果不关心输出格式,只想看看输出值,或许只是为了调试,可以用 Println 为我们
格式化输出。
fmt.Println(os.Args[1:])

这条语句的输出结果跟 strings.Join 得到的结果很像,只是被放到了一对方括号里。切片都
会被打印成这种格式。