Go语言规定了特定的字符序列,它们被称为关键字,又叫作保留字。我们不能把关键字作为标识符使用。
运算符是一个符号,通知编译器执行数学或逻辑操作。Go语言有丰富的内置运算符,可分为以下几类:
分类 | 运算符 | 说明 |
---|---|---|
算数运算符 | +,-,*,,%,++,- - | 基本与C相同,注意++和- -只是语句并不是表达式,不能把它直接赋值其他变量,b:=a++是错误的 |
关系运算符 | ==,!=,>,<,>=,<= | 用法基本与C相同 |
逻辑运算符 | &&,!,ll | 用法基本与C相同 |
按位运算符 | &,l,^,<<,>> | 用法基本与C相同 |
赋值运算符 | =,+=,-=,*=,/=,%=,<<=,>>=,&=,^=,l= | 用法基本与C相同 |
其它运算符 | *,& | *指向变量的指针,&返回变量的地址 |
初始化复合对象,类型标签,且左括号必须在类型的尾部。
// var a struct { x int } = { 100 } // syntax error
// var b []int = { 1, 2, 3 } // syntax error
// c := struct {x int; y string} // syntax error: unexpected semicolon or newline
// {
// }
var a = struct{ x int }{
100}
var b = []int{
1, 2, 3}
初始化值以“,”分割。可以分割为多行,但是最后一行必须以“,”或“}”结尾。
a := []int{
1,
2 // Error: need trailing comma before newline in composite literal
}
a := []int{
1,
2, // ok
}
b := []int{
1,
2 } // ok
x := 0
// if x > 10 // Error: missing condition in if statement
// {
// }
if n := "abc"; x > 0 { // 初始化语句未必就是定义变量,⽐比如 println("init") 也是可以的。
println(n[2])
} else if x < 0 { // 注意 else if 和 else 左⼤大括号位置。
println(n[1])
} else {
println(n[0])
}
支持三种循环方式,包括类 while 语法的用法。
s := "abc"
for i, n := 0, len(s); i < n; i++ { // 常⻅见的 for 循环,⽀支持初始化语句。
println(s[i])
}
n := len(s)
for n > 0 { // 替代 while (n > 0) {}
println(s[n]) // 替代 for (; n > 0;) {}
n--
}
for { // 替代 while (true) {}
println(s) // 替代 for (;;) {}
}
输出结果
call length.
0 97
1 98
2 99
3 100
1st value | 2nd value | ||
---|---|---|---|
string | index | s[index] | unicode.rune |
array/slice | index | s[index] | |
map | key | m[key] | |
channel | element |
s := "abc"
for i := range s { // 忽略 2nd value,⽀支持 string/array/slice/map。
println(s[i])
}
for _, c := range s { // 忽略 index。
println(c)
}
for range s { // 忽略全部返回值,仅迭代。
...
}
m := map[string]int{
"a": 1, "b": 2}
for k, v := range m { // 返回 (key, value)。
println(k, v)
}
a := [3]int{
0, 1, 2}
for i, v := range a {
// index、value 都是从复制品中取出。
if i == 0 {
// 在修改前,我们先修改原数组。
a[1], a[2] = 999, 999
fmt.Println(a) // 确认修改有效,输出 [0, 999, 999]。
}
a[i] = v + 100 // 使⽤用复制品中取出的 value 修改原数组。
}
fmt.Println(a) // 输出 [100, 101, 102]。
s := []int{1, 2, 3, 4, 5}
for i, v := range s { // 复制 struct slice { pointer, len, cap }。
if i == 0 {
s = s[:3] // 对 slice 的修改,不会影响 range。
s[2] = 100 // 对底层数据的修改。
}
println(i, v)
}
输出
0 1
1 2
2 100
3 4
4 5
x := []int{1, 2, 3}
i := 2
switch i {
case x[1]:
println("a")
case 1, 3:
println("b")
default:
println("c")
}
输出:
a //注意,case 1,3是或
x := []int{1, 2, 3}
i := 2
switch i {
case x[1]:
fmt.Println("a")
fallthrough
case 2, 3:
fmt.Println("b")
default:
fmt.Println("c")
}
输出结果:
a
b
switch {
case x[1] > 0:
println("a")
case x[1] < 0:
println("b")
default:
println("c")
}
switch i := x[2]; { // 带初始化语句
case i > 0:
println("a")
case i < 0:
println("b")
default:
println("c")
}
goto
跳转。区分大小写,未使用标签引发错误。func main() {
var i int
for {
println(i)
i++
if i > 2 { goto BREAK }
}
BREAK:
println("break")
EXIT: // Error: label EXIT defined and not used
}
标签
,break
和continue
可在多级嵌套循环中跳出。func main() {
L1:
for x := 0; x < 3; x++ {
L2:
for y := 0; y < 5; y++ {
if y > 2 {
continue L2
}
if x > 1 {
break L1
}
print(x, ":", y, " ")
}
println()
}
}
注意:break可以for、switch、select,而continue仅能用于for循环。
func main() {
x := 100
switch {
case x >= 0:
if x == 0 {
break
}
println(x)
}
}
select是Go中的一个控制结构,类似于用于通信的switch语句。每个case必须是一个通信操作,要么是发送要么是接收。select随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。一个默认的子句应该总是可运行的。
select {
case communication clause :
statement(s);
case communication clause :
statement(s);
/* 你可以定义任意数量的 case */
default : /* 可选 */
statement(s);
}
以下描述了 select 语句的语法:
示例
package main
import "fmt"
func main() {
var c1, c2, c3 chan int
var i1, i2 int
select {
case i1 = <-c1:
fmt.Printf("received ", i1, " from c1\n")
case c2 <- i2:
fmt.Printf("sent ", i2, " to c2\n")
case i3, ok := (<-c3): // same as: i3, ok := <-c3
if ok {
fmt.Printf("received ", i3, " from c3\n")
} else {
fmt.Printf("c3 is closed\n")
}
default:
fmt.Printf("no communication\n")
}
}
输出结果:
no communication
本部分简要介绍了保留字、运算符、表达式的初始化和控制流,最后补充了select控制流。熟悉这些用法,注意与C语言语法差异之处。
- Go 语言第一课
- Go 学习笔记(雨痕)
- Go 官网教程 Tour
- Go 语言教程