流程控制
Go语言支持最基本的三种程序运行结构:顺序结构、选择结构、循环结构。
- 顺序结构:程序按顺序执行,不发生跳转。
- 选择结构:依据是否满足条件,有选择的执行相应功能。
- 循环结构:依据条件是否满足,循环多次执行某段代码。
1 选择结构
1.1 if语句
1.1.1 if条件判断基本写法
package main import "fmt" func main(){ s := "屌丝" // if 和{ 就是条件,条件通常都是关系运算符 if s == "王思聪"{ //左括号和if在同一行 fmt.Println("左手一个妹纸,右手一个大妈") } // if 支持一个初始化语句,初始化语句和判断条件以分号隔开 if a := 10; a == 10 { //条件为真,指向{}语句 fmt.Println("a==10") } }
1.1.2 if ... else和if...else if ...else
package main import "fmt" func main(){ //1 a := 2 if a == 10{ fmt.Println("a == 10") } else { // else后面没有条件 fmt.Println("a != 10") } // 2 if a:=10; a == 10{ fmt.Println("a == 10") }else{ fmt.Println("a != 10") } if a:=20; a == 10{ fmt.Println("a == 10") }else if a > 10{ fmt.Println("a > 10") }else if a < 10{ fmt.Println("a < 10") }else{ fmt.Println("这是不可能的") } }
注意点:对于if...else if....else可以使用if 来替代,但是通常不会用
package main import "fmt" func main(){ if a:=10;a == 10{ fmt.Println("a == 10") }else if a>10{ fmt.Println("a>10") }else if a<10{ fmt.Println("a<10") } var b = 10 if b==10{ fmt.Println("b==10") } if b>10 { fmt.Println("b>10") } if b<10{ fmt.Println("b<10") } }
两个判断的执行结果一致,但是遇到这种场景,不会选择第二种,因为第二种要逐条判断,第一种如果第一个条件满足,后面的代码不会执行。
1.2 switch语句
Go里面switch默认相当于每个case最后带有break,匹配成功后不会自动向下执行其他case,而是跳出整个switch, 但是可以使用fallthrough强制执行后面的case代码:
package main import "fmt" func main(){ num := 10 switch num { //switch后面写的是变量本身 case 1: fmt.Println("按下的是1楼") break // go语言保留了break关键字,跳出switch,不写,默认包含 case 2: fmt.Println("按下的是2楼") case 3: fmt.Println("按下的是3楼") case 4: fmt.Println("按下的是4楼") case 5: fmt.Println("按下的是5楼") default: fmt.Printf("按下的是xxx楼") } }
如果使用fallthrough关键字,它表示不跳出switch,会将后面所有的case代码全部执行
package main import "fmt" func main(){ var num int fmt.Printf("请按下楼层:") fmt.Scan(&num) switch num { case 1: fmt.Println("按下的是1楼") fallthrough case 2: fmt.Println("按下的是2楼") fallthrough case 3: fmt.Println("按下的是3楼") fallthrough case 4: fmt.Println("按下的是4楼") fallthrough default: fmt.Printf("按下的XXX楼") } }
一个case后面可以跟多个条件,switch后面也可以不用跟变量
package main import "fmt" func main(){ // 支持一个初始化语句,初始化语句和变量本身,以分号分割 switch num:=5; num { case 1: fmt.Println("按下的是1楼") case 2: fmt.Println("按下的是2楼") case 3,4,5: // 可以跟多个条件 fmt.Println("按下的是yyyy楼") default: fmt.Println("按下的是xxxxx楼") } score := 85 switch { //可以没有条件 case score > 90: //case 后面可以放条件 fmt.Println("优秀") case score > 80: fmt.Println("良好") case score > 70: fmt.Println("一般") default: fmt.Println("其他") } }
2 循环语句
2.1 for
在go语言中只有for循环,语法为: for 初始化条件; 判断条件; 条件变化{}
package main import "fmt" func main(){ // for 初始化条件; 判断条件; 条件变化{ // } // 1+2+3+……+100 sum := 0 //1.初始化条件 i:=1 //2.判断条件是否为真,i<=100; 如果为真,执行循环体,如果为假,跳出 //3.条件变化 i++ //4.重复2,3,4 for i:=1; i<=100; i++{ sum += i } fmt.Println("sum = ", sum) }
使用python实现上述例子:
# for 循环 sum = 0 for i in range(101): sum += i print(sum) # while循环 i = 0 sum1 = 0 while 1: sum1 += i if i == 100: break i += 1 print(sum1)
python和go在循环上的语法区别还是很大的,要加以区分。
在go语言中,for后面不加任何东西,相当于python中的while 1
练习:使用python和go分别实现99表
# python
# for 版本 for i in range(1,10): for j in range(1,i+1): print("%d * %d = %d" % (j, i, i*j), end=" ") print("") # while 版本 n = 1 sum = 1 while n <= 9: i = 1 while i <= n: sum = i * n print("%d * %d = %d" %(n, i, sum), end=" ") i += 1 print("") n += 1
//go版本
package main import "fmt" func main() { for i:=1; i<=9; i ++{ for j:=1; j<=i; j++{ fmt.Printf("%d * %d = %d " , j, i, i*j) } fmt.Printf(" ") } }
2.2 range
关键字 range 会返回两个值,第一个返回值是元素的数组下标,第二个返回值是元素的值:
package main import "fmt" func main(){ str := "abc" // 通过for循环打印每个字符 for i:=0; i<len(str); i++{ fmt.Printf("str[%d] = %c ", i, str[i]) } // 迭代打印每个元素,默认返回两个值,一个是元素的索引,一个是元素的本身 for i, data := range str{ //支持 string/array/slice/map。 fmt.Printf("str[%d]=%c ", i, data) } for i:=range str{ // 第二个返回值,默认丢弃,返回元素的索引位置 fmt.Printf("str[%d] = %c ", i, str[i]) } for i,_:=range str{ // 第二个返回值,通过匿名变量丢弃,返回元素的索引位置 fmt.Printf("str[%d] = %c ", i, str[i]) } }
注意:python range() 函数可创建一个整数列表,一般用在 for 循环中。
3 跳转语句
3.1 break和continue
在循环里面有两个关键操作break和continue,break操作是跳出当前循环,continue是跳过本次循环。(和python中用法一致)
注意:break可于for、switch、select,continue仅能用于for循环。
package main
import (
"time"
"fmt"
)
func main() {
i := 0
for {
i ++
time.Sleep(time.Second) //延时1秒
if i == 5{
break // 跳出循环,如果嵌套多个循环,跳出最近的那个内循环
// continue //跳出本次循环下次继续
}
fmt.Println("i = ", i)
}
}
break语句还可以在语句后面添加标签,表示退出某个标签对应的代码块,标签要求必须定义在对应的for,switch和select的代码块上。举个例子:
func breakDemo(){ BREAKDEMO1: for i:=0;i<10;i++{ for j:=0;j<10;j++{ if j==2{ break BREAKDEMO1 } fmt.Printf("%v-%v ",i,j) } } fmt.Println("...") }
continue语句可以结束当前循环,开始下一次的循环迭代过程,仅限在for循环内使用。
在continue语句后添加标签后,表示开始标签对应的循环,例如:
func continueDemo() { forloop1: for i := 0; i < 5; i++ { // forloop2: for j := 0; j < 5; j++ { if i == 2 && j == 2 { continue forloop1 } fmt.Printf("%v-%v ", i, j) } } }
3.2 goto
用goto跳转到必须在当前函数内定义的标签:
package main import "fmt" func main() { //break //break is not in a loop, switch, or select //continue //continue is not in a loop // goto可以用在任何地方,但是不能跨函数使用 fmt.Println("11111111111111") goto End // goto是关键字,End是用户起的标签 fmt.Println("22222222222222") End: fmt.Println("333333333333333333333") }