这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天
本文主要介绍Go语言中的的for,if,switch三种结构。
for循环
在Go语言中,表达循环的方式只有for,for循环有三种形式,如下所示:
// Like a C for
for init; condition; post { }
// Like a C while
for condition { }
// Like a C for(;;)
for { }
可以发现,判断条件外不需要套小括号。
若想遍历数组、切片、字符串或者映射,或从信道中读取消息, range 子句能够帮你轻松实现循环。如以下代码所示:
for key, value := range oldMap {
newMap[key] = value
}
//如果只需要遍历第一项,去掉第二个就行了
for key := range m {
if key.expired() {
delete(m, key)
}
}
//若只需要该遍历中的第二个项(值),请使用空白标识符,即下划线来丢弃第一个值:
sum := 0
for _, value := range array {
sum += value
}
对于字符串,range 能够提供更多便利。它能通过解析 UTF-8, 将每个独立的 Unicode 码点分离出来。错误的编码将占用一个字节,并以符文 U+FFFD 来代替。
for pos, char := range "日本 \ x80 語" { // \x80 is an illegal UTF-8 encoding
fmt.Printf("character %#U starts at byte position %d\n", char, pos)
}
//res
character U+65E5 '日' starts at byte position 0
character U+672C '本' starts at byte position 3
character U+FFFD '�' starts at byte position 6
character U+8A9E '語' starts at byte position 7
最后,Go 没有逗号操作符,而 ++ 和 -- 为语句而非表达式。 因此,若你想要在 for 中使用多个变量,应采用平行赋值的方式 (因为它会拒绝 ++ 和 --).如下图所示:
// Reverse a
for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
a[i], a[j] = a[j], a[i]
}
if语句
if x > 0 {
return y
}
上述代码中,大括号是强制的。
if和switch可以接受初始化语句,因此可以用他们设置局部变量,如下图所示:
if err := file.Chmod(0664); err != nil {
log.Print(err)
return err
}
如果有else的话,if-else的结构如下所示:
if num := 9; num < 0 {
fmt.Println(num, "is negative")
} else if num < 10 {
fmt.Println(num, "has 1 digit")
} else {
fmt.Println(num, "has multiple digits")
}
上面代码中,else要和“ } ”在同一行,因为如果在“ } ”后回车后,编译器会将“}”之后的回车替换为“ ; ”,那么就是两个语句了。
switch语句
基本语法
switch condition {
case A:
...
case B:
...
default:
...
上述代码中,condition,default可有可无,并且default也不是强制在最下边,它可以放在case A,case B的上方,对最终结果没有影响。
func unhex(c byte) byte {
switch {
case '0' <= c && c <= '9':
return c - '0'
case 'a' <= c && c <= 'f':
return c - 'a' + 10
case 'A' <= c && c <= 'F':
return c - 'A' + 10
}
return 0
}
a := 2
switch a {
case 1:
fmt.Println("one")
case 2:
fmt.Println("two")
case 3:
fmt.Println("three")
case 4, 5:
fmt.Println("four or five")
default:
fmt.Println("other")
}
此外,switch…case…还可以用于类型选择,如下面代码所示:
var t interface{}
t = functionOfSomeType()
switch t := t.(type) {
default:
fmt.Printf("unexpected type %T", t) // %T 输出 t 是什么类型
case bool:
fmt.Printf("boolean %t\n", t) // t 是 bool 类型
case int:
fmt.Printf("integer %d\n", t) // t 是 int 类型
case *bool:
fmt.Printf("pointer to boolean %t\n", *t) // t 是 *bool 类型
case *int:
fmt.Printf("pointer to integer %d\n", *t) // t 是 *int 类型
}