5 控制语句
include
- 指针
- 递增递减语句
- 判断语句if
- 循环语句for
- switch 语句
- 跳转语句--> goto,break,continue
指针
go虽然保留了指针,但是与其他的编程语言不同的是,在Go当中不支持指针运算以及“->” 运算符,而直接采用“.” 选择符来操作指针目标对象的成员
- 操作符“&” 取变量地址,使用“*” 通过指针间接访问目标对象
- 默认值为nil 而非 NULL
代码例子
func main() {
a := 1
var p *int = &a // 把a的内存地址赋值给p
fmt.Println(*p) // 在打印p的时候加上*就可以把这个内存地址给取出来
fmt.Println(p) // 打印内存地址而已
}
递增递减语句
在Go当中,++与--是作为语句而不是作为表达式,表示为自增1或者自减1
自增自减语句只能单独作为一条语句执行,不能放在等号的右边
func main() {
a, b := 1, 2
a-- // 自减1,只能单独作为
b++ // 自增1
var p *int = &a
fmt.Println(*p)
fmt.Println(b)
}
判断语句if
- 条件表达式没有括号
- 支持一个初始化表达式(可以是并行方式)
- 左大括号必须和条件语句或者else在同一行
- 支持单行模式
- 初始化语句中的变量为block级别,同时隐藏外部同名变量
代码例子:
下面这个代码需要说明的是:if 条件申明的变量,该变量作用域只存在这个if判断语句中,其他不在if语句中的语句是获取不到这个变量的,和for循环语句一样。
func main() {
if a := 1; a > 1 { //大括号必须和if放在同一行
fmt.Println(a)
} else {
fmt.Println("less than 1")
}
fmt.Println(a) // 这个打印会报错的
}
下面这段代码说的是,if判断语句之外有一个变量a,if语句中也有一个变量a,那么在执行代码的时候,if语句中的a会暂时覆盖掉语句之外的a,也就是把外面的a给隐藏起来了,只有当if语句执行完后才会把if语句外的a给显示出来
func main() {
a := 3
if a := 1; a > 1 {
fmt.Println(a)
} else {
fmt.Println("less than 1")
}
fmt.Println(a) // 打印结果为3
}
循环语句for
- go只有for一个循环语句关键字,但是支持三种形式
- 初始化和步进表达式可以是多个值
- 条件语句每次循环都会被重新检查,因此不建议在条件语句中使用函数,尽量提前计算好条件并以变量或者常量代替
- 左大括号必须和条件语句在同一行
for第一种方式(最常见)
无限循环的,等同于while True
func main() {
a := 3
for { // 无限循环的
a++
if a > 10 {
fmt.Println(a)
break
} else {
fmt.Println("less than ", a)
}
}
fmt.Println(a)
}
for第二种方式(最常见)
func main() {
a := "string"
for i := 1; i < 30; i++ {
fmt.Println(i)
}
fmt.Println(a)
}
第三种方式:
func main() {
a := 4
for a <= 5 {
a++
fmt.Println("----", a)
}
}
switch 语句
- 可以使用任何类型或者表达式作为条件语句
- 不需要写break,一旦条件符合自动终止
- 如希望继续下一个case,需要使用fallthrough语句
- 支持一个初始化表达式(可以是并行方式),右侧需要跟分好
- 左大括号必须和条件在同一行
- switch匹配的变量,如果是switch后面定义的常量或者变量,那么作用域仅限在switch语句之内。
请看代码例子:
第一种形式:
switch 后面接一个变量,然后由case去匹配
func main() {
a := 1
switch a {
case 0:
fmt.Println("a=0", a)
case 1:
fmt.Println("a=1", a)
default:
fmt.Println("None", a)
}
}
第二种形式
case 里面有表达式,直接在case匹配
func main() {
a := 1
switch {
case a >= 0:
fmt.Println("a=0", a)
fallthrough // fallthrought表示即使通过了这个匹配条件,也得继续匹配后面的条件
case a >= 1:
fmt.Println("a=1", a)
default:
fmt.Println("None", a)
}
}
第三种形式
switch里面执行赋值语句
func main() {
switch a := 2; {
case a >= 0:
fmt.Println("a=0", a)
fallthrough
case a >= 1:
fmt.Println("a=1", a)
default:
fmt.Println("None", a)
}
}
跳转语句--> goto,break,continue
- 三个语法都可以配合标签使用,continue,break也可以不配合标签使用,continue,break不配合使用就和其他语言一样的用法了。
- 标签名区分大小写,若不使用会造成编译错误
- Break与continue配合标签可用于多层循环的跳出
- Goto是调整执行位置,与其他2个语句配合标签的结果并不相同
break-LABEL1
break 后面紧接一个label标签能够快速到那个标签下的代码,不管你的代码有多少层循环,需要注意的是,for循环必须是在LABEL标签以内才能生效,与goto是相反的。请看下面的代码
func main() {
LABEL1:
for i := 0; i < 10; i++ {
if i > 3 {
fmt.Println(i)
break LABEL1 // break LABEL1 能够立即跳到LABEL1除for以外的代码,所他这步break后,
//直接走打印break的代码了。
}
}
fmt.Println("break ")
}
goto-LABEL
goto 后面紧跟着的LABEL是放在for循环下面的代码的,不是像break一样,label包裹着for。如下的代码所示,goto LABLE1 后直接到了println这个代码了
func main() {
for i := 0; i < 10; i++ {
if i > 3 {
fmt.Println(i)
goto LABEL1
}
}
LABEL1:
fmt.Println("break ")
}
continue
continue是继续到指定标签中执行。
LABEL1:
for i := 0; i < 10; i++ {
fmt.Println(i)
continue LABEL1
}
fmt.Println("ok ----> ")