Go的循环语句
FOR循环
package main
import {
"fmt"
"os"
}
func main() {
var s1,s2 string
for i :=1, i < len(os.Args) ; i++ { // 若改为 :=0 则输出的是被执行命令本身的名字即 Args[0]
s1 += s2 + os.Args[i]
s2 = " "
}
fmt.Println(s1) // 输出为空
}
Go的for循环的条件不需要加() 而{}强制添加
Go的循环因子不需要定义类型而是使用 := 初始值,程序执行时会自动匹配其类型
Go的os包以跨平台的方式,提供了一些与操作系统交互的函数和变量
Go的循环只有for循环一种,不过针对不同的循环因子分为不同的情况
os.Args[0] 输出的是被执行命令本身的名字
for initialization; condition; post {
// zero or more statements
}
for循环三个部分不需括号包围。大括号强制要求,左大括号必须和post语句在同一行。
initialization(初始化)语句是可选的,在循环开始前执行。initalization如果存在,必须是一条简单语句(simple statement),即,短变量声明、自增语句、赋值语句或函数调用。condition(条件语句)是一个布尔表达式(boolean expression),其值在每次循环迭代开始时计算。如果为true则执行循环体语句。post语句在循环体执行结束后执行,之后再次对condition求值。condition值为false时,循环结束。
for循环的这三个部分每个都可以省略,如果省略 initialization 和 post,分号也可以省略:
// a traditional "while" loop
for condition {
// ...
}
package main
import (
"fmt"
)
func main() {
sum := ""
param := "a"
for sum == "" {
sum = param
fmt.Println(sum)
}
}
如果连condition也省略了,像下面这样:
// a traditional infinite loop
for {
// ...
}
package main
import (
"fmt"
)
func main() {
sum := ""
param := "a"
for {
sum = param
fmt.Println(sum)
}
}
这就变成一个无限循环,尽管如此,还可以用其他方式终止循环,如一条break或return语句。`
for循环的另一种形式,在某种数据类型的区间(range)上遍历,如字符串或切片。echo的第二版本展示了这种形式:
// Echo2 prints its command-line arguments.
package main
import (
"fmt"
"os"
)
func main() {
s, sep := "", ""
for _, arg := range os.Args[1:] {
s += sep + arg
sep = " "
}
fmt.Println(s)
}
每次循环迭代,range产生一对值:索引以及在该索引处的元素值。这个例子不需要索引,但range的语法要求,要处理元素,必须处理索引。一种思路是把索引赋值给一个临时变量(如temp)然后忽略它的值,但Go语言不允许使用无用的局部变量(local variables),因为这会导致编译错误。
package main
import (
"fmt"
"os"
)
func main() {
sum, param := "", ""
for _, arg := range os.Args[0:] {
sum = param + arg
fmt.Println(sum)
}
}
Go语言中这种情况的解决方法是用空标识符(blank identifier),即_(也就是下划线)。空标识符可用于在任何语法需要变量名但程序逻辑不需要的时候(如:在循环里)丢弃不需要的循环索引,并保留元素值。大多数的Go程序员都会像上面这样使用range和_写echo程序,因为隐式地而非显式地索引os.Args,容易写对。
echo的这个版本使用一条短变量声明来声明并初始化s和seps,也可以将这两个变量分开声明
声明一个变量有好几种方式,下面这些都等价:
s := ""
var s string
var s = ""
var s string = ""
用哪种不用哪种,为什么呢?第一种形式,是一条短变量声明,最简洁,但只能用在函数内部,而不能用于包变量。第二种形式依赖于字符串的默认初始化零值机制,被初始化为""。第三种形式用得很少,除非同时声明多个变量。第四种形式显式地标明变量的类型,当变量类型与初值类型相同时,类型冗余,但如果两者类型不同,变量类型就必须了。
一般使用前两种形式中的某个,初始值重要的话就显式地指定变量的类型,否则使用隐式初始化。
如前文所述,每次循环迭代字符串s的内容都会更新。+=连接原字符串、空格和下个参数,产生新字符串,并把它赋值给s。s原来的内容已经不再使用,将在适当时机对它进行垃圾回收。
如果连接涉及的数据量很大,这种方式代价高昂。一种简单且高效的解决方案是使用strings包的Join函数:
func main() {
fmt.Println(strings.Join(os.Args[1:], " "))
}

浙公网安备 33010602011771号