流程控制
Go 语言 if 条件语句
条件语句需要开发者通过指定一个或多个条件,并通过测试条件是否为 true 来决定是否执行指定语句,并在条件为 false 的情况在执行另外的语句。
if 语句 由一个布尔表达式后紧跟一个或多个语句组成。
if 在布尔表达式为 true 时,其后紧跟的语句块执行,如果为 false 则不执行。
第一种,直接判断bool类型
package main
import "fmt"
func main() {
if true {
fmt.Println("true")
}
}
package main
import "fmt"
func main() {
b := true
if b {
fmt.Println("b := true")
}
}
第二种,表达式中判断bool类型
package main
import "fmt"
func main() {
var i int
if i == 0 {
fmt.Println("i == 0")
}
}
package main
import "fmt"
func main() {
var str string
if str == "" {
fmt.Println(`str == ""`)
}
}
第三种,通过 &&逻辑与 ||逻辑或 !逻辑非,判断bool类型
package main
import "fmt"
func main() {
a := 10
b := 20
if a > 0 && a < b {
fmt.Println("a > 0 && a < b")
}
if a < 10 || b == 20 {
fmt.Println("a < 10 || b == 20")
}
if !(a == b) {
fmt.Println("!(a == b)")
}
}
第四种,表达式中先变量赋值后判断bool类型
package main
import "fmt"
func main() {
if age := 18; age == 18 {
fmt.Println("age == 18")
}
}
if…else 语句
if 语句 后可以使用可选的 else 语句, else 语句中的表达式在布尔表达式为 false 时执行。实例如下:
package main
import (
"fmt"
)
func main() {
i := 10
if i < 10 {
fmt.Println("i<10")
} else if i == 10 {
fmt.Println("i=10")
} else {
fmt.Println("i>10")
}
}
if 嵌套语句
你可以在 if 或 else if 语句中嵌入一个或多个 if 或 else if 语句。实例如下:
package main
import (
"fmt"
)
func main() {
name := "leyu"
age := 18
if name == "leyu" {
if age == 18 {
fmt.Println("The old boy welcomes you.")
}
}
}
Go语言switch条件语句
switch 语句用于基于不同条件执行不同动作。
switch 语句用于基于不同条件执行不同动作,每一个 case 分支都是唯一的,所有 case 分支的参数必须是相同的类型,语句执行的过程从上至下,直到找到匹配项,匹配项后面也不需要再加 break 默认自动终止。
switch 语句
第一种,直接判断
package main
import "fmt"
func main() {
var i = 0
switch i {
case 0:
case 1:
fmt.Println(1)
case 2:
fmt.Println(2)
default:
fmt.Println("default")
}
}
第二种,带初始化语句
package main
import "fmt"
func main() {
names := []string{"Linux", "Golang", "Java", "Python"}
switch name := names[0]; name {
case "Golang":
fmt.Println("Golang")
case "Java":
fmt.Println("Java")
case "Python":
fmt.Println("Python")
default:
fmt.Println("oldboy")
}
}
第三种,一个 case 多个可能符合条件的值
package main
import "fmt"
func main() {
var i = 1
switch i {
case 0, 1:
fmt.Println("0 or 1")
case 2:
fmt.Println("2")
default:
fmt.Println("default")
}
}
第四种,省略条件表达式应用
package main
import "fmt"
func main() {
var i = 10
switch {
case i >= 0 && i < 10:
fmt.Println("i > 0 and i < 10")
case i >= 10 && i < 20:
fmt.Println("i > 10 and i < 20")
default:
fmt.Println("default")
}
}
第五种,fallthrough应用
Go语言 switch 语句每个 case 最后默认带有break,匹配成功后不会自动向下执行其他 case,而是跳出整个switch,可以使用 fallthrough 语句强制执行后面的 case 代码。
package main
import "fmt"
func main() {
var i = 0
switch i {
case 0:
fmt.Println("fallthrough")
fallthrough
case 1:
fmt.Println(1)
case 2:
fmt.Println(2)
default:
fmt.Println("default")
}
}
Go语言 for 循环语句
for循环是一个循环控制结构,可以执行指定次数的循环。
三种循环方式
第一种,常见的 for 循环,支持初始化语句
for init; condition; post {
}
init: 一般为赋值表达式,给控制变量赋初值;
condition: 关系表达式或逻辑表达式,循环控制条件;
post: 一般为赋值表达式,给控制变量增量或减量。
for语句执行过程如下:
① 先对表达式 init 赋初值;
②判别赋值表达式 init 是否满足给定 condition 条件,若其值为真,满足循环条件,则执行循环体内语句,然后执行 post,进入第二次循环,再判别 condition;否则判断 condition 的值为假,不满足条件,就终止for循环,执行循环体外语句。
package main
import (
"fmt"
)
func main() {
for i := 1; i < 10; i++ {
fmt.Println(i)
}
}
第二种,关系表达式或逻辑表达式控制循环
for condition { }
实例如下:
package main
import (
"fmt"
)
func main() {
i := 0
for i < 5 {
i++
}
for i == 5 {
fmt.Println(i)
break
}
}
第三种,无限循环
for {
}
for true {
}
实例如下:
package main
import (
"fmt"
"time"
)
func main() {
for {
fmt.Println("无限循环 for {}")
time.Sleep(time.Second)
}
}
循环嵌套
在 for 循环中可以嵌套一个或多个 for 循环,实例如下:
1、使用循环嵌套来输出九九乘法表:
package main
import "fmt"
func main() {
for i := 1; i < 10; i++ {
for j := 1; j <= i; j++ {
fmt.Printf("%d * %d = %2d\t", i, j, i*j)
}
fmt.Println()
}
}
2、使用循环嵌套来输出 2 到 100 间的素数:
package main
import "fmt"
func main() {
var i, j int
for i = 2; i < 100; i++ {
for j = 2; j <= (i / j); j++ {
if i%j == 0 {
break
}
}
if j > (i / j) {
fmt.Printf("%2d 是素数\n", i)
}
}
}
Go语言 range 循环语句
Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对的 key 值。
字符串遍历
1、for range 英文字符串,key 值按照+1顺序递增
package main
import (
"fmt"
)
func main() {
var str string = "leyu"
for k, v := range str {
fmt.Println(k, string(v))
}
}
2、for range 包含中文的字符串,英文字符 key 值按照+1顺序递增,中文字符 key 值按照+3顺序递增
package main
import (
"fmt"
)
func main() {
var str string = "技术迎来潮流"
for k, v := range str {
fmt.Println(k, string(v))
}
}
数组遍历
1、for range 数组程序会复制对象,key、value 都是从复制品中取出
package main
import (
"fmt"
)
func main() {
arr := [5]int{1, 2, 3, 4, 5}
for k, v := range arr {
if k == 0 {
arr[0], arr[1] = 1000, 1000
fmt.Println("修改原数组:", arr)
}
// 使用复制品中取出的 value 修改原数组
arr[k] = v + 100
}
fmt.Println(arr)
}
2、多维数组遍历
package main
import (
"fmt"
)
func main() {
var arr [2][3]int = [2][3]int{{1, 2, 3}, {2, 4, 6}}
for k1, v1 := range arr {
for k2, v2 := range v1 {
fmt.Printf("%d*%d=%d ", k1+1, k2+1, v2)
}
fmt.Printf("\n")
}
}
3、数组遍历值拷贝行为会造成性能问题,建议数组遍历使用引用类型slice,或数组指针。
package main
import "fmt"
func main() {
arr := [5]int{1, 2, 3, 4, 5}
arrP := &arr
for k, _ := range arrP {
if k == 0 {
arrP[0], arrP[1] = 1000, 1000
fmt.Println("修改原数组:", arr)
}
arrP[k] += 100
}
fmt.Println(arr)
}
slice 遍历
将所需数据 copy 到较小的 slice,以便释放底层数组内存
package main
import (
"fmt"
)
func main() {
arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
slice := arr[:]
for key, value := range slice {
fmt.Printf("key: %v , value : %v\n", key, value)
}
}
map 遍历
map 遍历不能保证迭代返回次序,通常是随机结果,具体和版本实现有关。
package main
import (
"fmt"
)
func main() {
m := map[int]string{
1: "leyu",
2: "Linux",
3: "Golang",
4: "Python",
5: "Java",
6: "DBA",
}
for k, v := range m {
fmt.Printf("%d => %s \n", k, v)
}
}
channel 遍历
package main
import "fmt"
func main() {
var ch chan int
ch = make(chan int, 10)
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
for v := range ch {
fmt.Println(v)
}
}
注意:如果没有 close() 因为存入管道10个数字,然后无限取数据,在取出来第10个数据,在次range管道,会dead lock。
Go语言循环控制语句
循环控制语句可以控制循环体内语句的执行过程。
GO 语言支持 goto、break、continue 三种循环控制语句,三个语句都可以配合标签( label )使用,标签名区分大小写,定义后不使用会造成编译错误。
goto 语句
Go语言支持在函数内 goto 跳转。goto 语句可以无条件地转移到过程中指定的行,通常与条件语句配合使用。可用来实现条件转移、构成循环、跳出循环体等功能。实例如下:
1、先定义标签后定义goto语句
package main
import "fmt"
func main() {
var i int = 10
GO:
for i < 20 {
if i == 15 { //跳过迭代
i = i + 1
goto GO
}
fmt.Printf("i的值为 : %d\n", i)
i++
}
}
2、先定义goto语句后定义标签
package main
import "fmt"
func main() {
var i int
for {
fmt.Println(i)
i++
if i > 2 {
goto leyu
}
}
leyu:
fmt.Println("golang")
}
注意:goto语句与标签之间不能有变量声明,否则编译错误。
package main
import "fmt"
func main() {
fmt.Println("start")
goto Loop
var say = "hello leyu"
fmt.Println(say)
Loop:
fmt.Println("end")
}
编译错误:
./main.go:7:7: goto Loop jumps over declaration of say at ./main.go:8:6
break 语句
1、break 语句中断当前 for 循环,并开始执行循环之后的语句
package main
import "fmt"
func main() {
var i int = 10
for i < 20 {
fmt.Printf("i 的值为 : %d\n", i)
i++
if i > 15 {
// break 语句跳出循环
break
}
}
}
2、break 语句中断当前 for range 循环,并开始执行循环之后的语句
package main
import (
"fmt"
)
func main() {
m := map[int]string{
1: "leyu",
2: "Linux",
3: "Python",
4: "Java",
5: "Golang",
}
for k, v := range m {
fmt.Printf("%d => %s \n", k, v)
if v == "Golang" {
// break 语句跳出循环
break
}
}
}
3、break 语句在执行一条 case 后跳出 switch 循环
package main
import (
"fmt"
)
func main() {
name := "Golang"
switch name {
case "oldboy":
fmt.Println(name)
break
case "Linux":
fmt.Println(name)
break
case "Golang":
fmt.Println(name)
break
case "Python":
fmt.Println(name)
break
case "Java":
fmt.Println(name)
break
case "DBA":
fmt.Println(name)
break
}
}
4、break 语句在执行一条 case 后跳出 select 循环
package main
import "fmt"
func main() {
var ch chan int
ch = make(chan int, 1)
// ch <- 1
select {
case i := <-ch:
fmt.Printf("received %d %s", i, " from ch\n")
break
default:
fmt.Println("break")
break
}
}
5、Break label 语句 跳出多层嵌套循环
package main
import (
"fmt"
)
func main() {
fmt.Println("start")
Exit:
for i := 0; i < 9; i++ {
for j := 0; j < 9; j++ {
if i+j > 15 {
fmt.Println("exit")
break Exit
}
}
}
fmt.Println("end")
}
break 标签除了可以跳出 for 循环,还可以跳出 select、switch 循环。
注意:label要写在循环的开始而不是结束的地方,和goto语句不一样。
package main
import (
"fmt"
)
func main() {
fmt.Println("start")
for i := 0; i < 9; i++ {
for j := 0; j < 9; j++ {
if i+j > 15 {
fmt.Println("exit")
break Exit
}
}
}
Exit:
fmt.Println("end")
}
编译错误:
./main.go:14:11: break label not defined: Exit
./main.go:18:1: label Exit defined and not used
continue 语句
1、continue 语句在 for 循环和for range 循环中用于跳过当前循环的剩余语句,然后继续进行下一轮循环。
package main
import "fmt"
func main() {
// for 循环
for i := 0; i < 5; i++ {
if i == 2 {
continue
}
fmt.Printf("i 的值为 : %d\n", i)
}
// for range 循环
sli := []string{"Linux", "Python", "Golang", "Java"}
for _, v := range sli {
fmt.Println(v)
if v != "Golang" {
continue
}
fmt.Println("The old boy welcomes you.")
}
}
2、continue label 语句可在多级嵌套循环中跳出
package main
import "fmt"
func main() {
BreakLabel:
for i := 0; i < 3; i++ {
ContinueLabel:
for j := 0; j < 5; j++ {
if j > 2 {
continue ContinueLabel
}
if i > 1 {
break BreakLabel
}
fmt.Print(i, ":", j, " ")
}
fmt.Println()
}
}