numbers1 := []int{1, 2, 3, 4, 5, 6} // 声明并初始化int类型的切片
for i := range numbers1 { // range子句迭代切片汇总的所以元素值
if i == 3 {
numbers1[i] |= i
}
}
fmt.Println(numbers1)
for语句被执行的时候,range关键字右边(range表达式)的numbers1会被先求值,range表达式的结果可以是数组、数组的指针、切片、字符串、字典或允许接收操作的通道中的某一个,并且结果只能有一个。
对于不同种类的range表达式结果值,for语句的迭代变量的数量可以有所不同。上述切片的的迭代变量可以有两个,切片中的索引值和迭代对应的某一个值。
当range表达式只有一个迭代变量的时候,数组、数组的指针、切片、字符串的元素值都是无处安放的,只能按照从小到大的顺序给出一个个索引值。
numbers2 := [...]int{1, 2, 3, 4, 5, 6} // munbers2是数组,为值类型
maxIndex2 := len(numbers2) - 1
for i, e := range numbers2 {
if i == maxIndex2 {
numbers2[0] += e
} else {
numbers2[i+1] += e
}
}
fmt.Println(numbers2)
numbers3 := []int{1, 2, 3, 4, 5, 6} // mumber3是切片,为引用类型
maxIndex3 := len(numbers3) - 1
for i, e := range numbers3 {
if i == maxIndex2 {
numbers3[0] += e
} else {
numbers3[i+1] += e
}
}
fmt.Println(numbers3)
只有switch表达式的结果值与某个case表达式中的任意一个子表达式的结果值相等,该case表达式所属的case子句就会被选中,case子句被选中后,附带在case表达式后边的语句会被执行,其他case子句会被忽略。
value1 := [...]int8{0, 1, 2, 3, 4, 5, 6}
switch 1 + 3 { // switch表达式,结果值为无类型常量时,自动转换为此常量值默认的类型
case value1[0], value1[1]: // case表达式,case表达式中的结果值与switch表达式中的结果值类型不同
fmt.Println("0 or 1")
case value1[2], value1[3]:
fmt.Println("2 or 3")
case value1[4], value1[5], value1[6]:
fmt.Println("4 or 5 or 6")
}
在case子句附带的语句列表中包含fallthrough
语句,那么紧挨在它下边的那个case自己附带的语句也会被执行。
因为存在上述判等操作,对switch表达式的结果类型和case表达式的结果类型有要求。
如果表达式的结果类型有某个接口类型,那么一定要检查他们的动态值是否具有可比性。
switch语句在case子句的选择上具有唯一性,因此不允许case表达式结果值存在相等的情况(不论这些结果值相等的子表达式,是否存在于不同的case表达式中)。
// 无法通过编译
value5 := [...]int8{0, 1, 2, 3, 4, 5, 6}
switch value5[4] {
case value5[0], value5[1], value5[2]:
fmt.Println("0 or 1 or 2")
case value5[2], value5[3], value5[4]:
fmt.Println("2 or 3 or 4")
case value5[4], value5[5], value5[6]:
fmt.Println("4 or 5 or 6")
}
// 可以通过编译
value5 := [...]int8{0, 1, 2, 3, 4, 5, 6}
switch value5[4] {
case value5[0], value5[1], value5[2]:
fmt.Println("0 or 1 or 2")
case value5[2], value5[3], value5[4]:
fmt.Println("2 or 3 or 4")
case value5[4], value5[5], value5[6]:
fmt.Println("4 or 5 or 6")
}
上述第二种方式对类型判断switch语句无效。
类型switch语句中的case表达式的子表达式,都必须直接由类型字面量表示,而无法通过间接的方式表示。
value6 := interface{}(byte(127))
switch t := value6.(type) { // 类型switch语句
case uint8, uint16:
fmt.Println("uint8 or uint16")
case byte: // byte为unit8的别名类型,无法通过编译
fmt.Printf("byte")
default:
fmt.Printf("unsupported type: %T", t)
}
case子句的编写顺序很重要,最上边的case子句中的子表达式总是会被最先求值,在判等的时候顺序也是这样。因此,如果某些case表达式的结果值有重复,那么位置靠上的case子句总会被选中。