05-Go语言基础之流程控制
Golang程序的流程控制决定程序如何执行,主要有三大流程控制,顺序控制、分支控制、循环控制。
条件语句需要定义一个或多个条件,并且对条件测试的true或false来决定是否执行。
Go 语言提供了以下几种条件判断语句:
| 语句 | 描述 |
|---|---|
| if 语句 | if 语句 由一个布尔表达式后紧跟一个或多个语句组成。 |
| if...else 语句 | if 语句 后可以使用可选的 else 语句, else 语句中的表达式在布尔表达式为 false 时执行。 |
| if 嵌套语句 | 你可以在 if 或 else if 语句中嵌入一个或多个 if 或 else if 语句。 |
| switch 语句 | switch 语句用于基于不同条件执行不同动作。 |
| select 语句 | select 语句类似于 switch 语句,但是select会随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。 |
if判断语句
顺序控制
代码自上而下逐行执行,中间没有判断、跳转,按默认流程执行,即顺序控制。
分支控制
让程序有选择的执行,有单分支、双分支、多分支
单分支
if 表达式为真{
//代码
}else{
//否则进入此语句块
}
案例
package main
import "fmt"
func main() {
var age int
fmt.Println("请输入您的年纪:")
//获取用户输入,传入变量地址,防止值拷贝
fmt.Scanln(&age)
if age > 18 {
fmt.Println("已满18,允许访问!!")
}
}
/*
请输入您的年纪:
19
已满18,允许访问!!
*/
多重if嵌套
if表判断、else表转折关系。
package main
import "fmt"
func main() {
a := 100
b := 200
if a == 100 {
if b == 200 {
fmt.Println("a为100,b为200")
} else {
fmt.Println("a或b有一个不匹配")
}
} else {
fmt.Println("a甚至不等于100")
}
}
双分支
package main
import "fmt"
func main() {
var age int
fmt.Println("请输入您的年纪:")
//获取用户输入,传入变量地址,防止值拷贝
fmt.Scanln(&age)
if age >= 18 {
fmt.Println("已满18,允许访问!!")
} else {
fmt.Println("未满18,回家写作业!!")
}
}
多分支

package main
import (
"fmt"
)
/*
有一核桃,将被进行以下处理
干干巴巴、麻麻赖赖、那就盘他!!
通透圆润,好东西!!
甭管什么东西,盘他!!
*/
func main() {
var hetao string
fmt.Println("请输入核桃的成色")
fmt.Scanln(&hetao) //写入变量
//多分支判断
if hetao == "干干巴巴,麻麻赖赖" {
fmt.Println("盘他!!")
} else if hetao == "通透圆润" {
fmt.Println("好东西!!")
} else {
fmt.Println("管他三七二十,来啥盘啥!!")
}
}
练习
package main
import "fmt"
// 成绩判断,分三挡 优秀,普通,差
func f1() {
score := 59
if score >= 90 {
fmt.Println("优秀毕业生")
} else if score >= 60 {
fmt.Println("普通毕业生")
} else {
fmt.Println("差生,留级")
}
fmt.Println("得分情况:", score)
}
// if后面支持写复杂语句
func f2() {
//成绩判断
//注意如此写法,score变量,只存在于if分支作用域表内
if score := 44; score >= 90 {
fmt.Println("优秀毕业生")
} else if score >= 60 {
fmt.Println("分数", score)
fmt.Println("及格了")
} else {
fmt.Println("分数", score)
fmt.Println("不及格,补考吧")
}
//fmt.Println("外部访问不到score变量",score)
}
func main() {
//f1()
f2()
}
Go switch语句
switch语句用于基于不同条件执行不同动作,每一个case分支唯一,自上而下逐一测试,直到匹配结束,默认自动终止,不需要break。
如果某变量需要有较多的判断分支,使用if语句太过于繁琐,switch语句可以方便的大量的值进行条件判断。
switch基本语法
- switch后面跟着表达式(变量、常量、有返回值函数等)
- case后面的表达式必须和switch表达式数据类型一致
- case后可以有多个表达式
- case后面表达式常量不得重复
- Go语言规定每个
switch只能有一个default分支。 - 一个分支可以有多个值,多个case值中间使用英文逗号分隔。
- 判断的具体数值不多,符合整数、浮点数、字符、字符串等类型,建议用switch。
- 对bool类型的判断,用if,if可控范围更广。
package main
import "fmt"
func main() {
var week int
fmt.Println("请输入星期几:")
fmt.Scanln(&week)
switch week {
case 1:
fmt.Println("星期一,上班!!")
case 2, 3, 4, 5:
fmt.Println("星期二到星期五,你还得上班!!")
case 6:
fmt.Println("周六你就想休息?加班!!")
case 7:
fmt.Println("终于tm周日了。。老子迟早要辞职,终于能休息了!!")
default:
fmt.Println("输入错误你就必须得上班!!")
}
fmt.Println("今天星期:", week)
}
/*
请输入星期几:
7
终于tm周日了。。老子迟早要辞职,终于能休息了!!
*/
switch作用域
package main
import "fmt"
func testSwitch() {
// 该变量n,只存在于switch作用域内
switch n := 71; n {
case 1, 3, 5, 7, 9:
fmt.Println("奇数")
case 2, 4, 6, 8:
fmt.Println("偶数")
default:
fmt.Println(n)
}
// 不支持 fmt.Println("数字是:", n)
}
func main() {
testSwitch()
}
case分支也支持表达式
package main
import "fmt"
func main() {
var score int
fmt.Println("请录入你的成绩:>")
fmt.Scanln(&score)
switch {
case score > 90:
fmt.Println("成绩优秀")
case score >= 70:
fmt.Println("及格中等")
case score >= 60:
fmt.Println("勉强及格了")
default:
fmt.Println("恭喜你,考试不及格")
}
}
fallthrough语句
switch之穿透fallthrough,在case语句块后添加fallthrough会继续执行下一个case
package main
import "fmt"
func main() {
var score int
fmt.Println("请录入你的成绩:")
fmt.Scanln(&score)
switch {
case score > 90:
fmt.Println("成绩优秀")
fallthrough
case score >= 70:
fmt.Println("及格中等")
case score >= 60:
fmt.Println("勉强及格了")
default:
fmt.Println("恭喜你,考试不及格")
}
}
Go循环for语句
Go的for循环是一个循环控制结构,可以执行循环次数。
Go 语言中的所有循环类型均可以使用for关键字来完成。
条件表达式返回true时循环体不停地进行循环,直到条件表达式返回false时自动退出循环。
for循环的基本格式如下:
for 初始语句;条件表达式;结束语句{
循环体语句
}
for案例
package main
import "fmt"
func forDemo() {
// 语法1,循环条件是布尔值
num := 0
for num < 10 {
fmt.Println("超哥带你学golang,www.yuchaoit.cn")
num++
}
// 语法2,死循环,go没有while语句
for {
fmt.Println("死循环了!不能执行,容易死机!")
}
}
func forDemo2() {
// 语法3,标准语法,如打印数字 1~10
//for i := 1; i <= 10; i++ {
// fmt.Printf("数字:%d\n", i)
//}
//语法4,go的初始语句可以省略,同上
num := 1
for num <= 10 {
fmt.Printf("数字:%d\n", num)
num++
}
}
func forDemo3() {
// 语法5,死循环,以及循环控制,依然是打印1~10
num := 0
for {
if num >= 10 {
break
}
fmt.Printf("数字:%d\n", num)
num++
}
}
/*
for range语句用于遍历字符串,数组,切片,map,channel
for range遍历的返回值规律
1. 数组、切片、字符串,返回的是 index、value
2. map返回 key,value
3. channel 只返回通道内的值
*/
func forDemo4() {
teacher := "yuchao"
for i, v := range teacher {
fmt.Printf("%v:%c\n", i, v)
}
}
func main() {
forDemo4()
}
99乘法表

两数相乘
package main
import "fmt"
func main() {
var num int
fmt.Println("请输入层数:")
fmt.Scanln(&num)
// k 变量表示每一层
for k := 1; k <= num; k++ {
// j表示每一层,打印数量
for j := 1; j <= k; j++ {
fmt.Printf("%d * %d = %d\t", j, k, j*k)
}
fmt.Println()
}
}
网站三次登录
package main
import "fmt"
func main() {
var name string
var pwd string
var loginNum = 3
// 循环限制三次
for i := 1; i <= 3; i++ {
fmt.Println("请输入账号:")
fmt.Scanln(&name)
fmt.Println("再输入密码:")
fmt.Scanln(&pwd)
if name == "yuchao" && pwd == "yuchao123" {
fmt.Println("*****欢迎超哥*******")
break
} else {
loginNum--
fmt.Println("账号或密码错误!!!")
fmt.Printf("登录次数还剩%d次\n", loginNum)
}
}
}
Go循环控制
Go语言的goto语句可以无条件的跳转到指定的代码行执行。
goto语句一般与条件语句结合,实现条件转义,跳出循环体等。
Go程序不推荐使用goto,以免造成程序混乱,难以阅读,了解即可。
如何退出多层for循环
package main
import "fmt"
func gotoDemo() {
var flag bool
//如何一次性退出 所有嵌套的for?
for k := 0; k < 10; k++ {
for j := 0; j < 10; j++ {
//期望到2的时候退出所有for
if j == 2 {
//单独一个break只能退出当前for
flag = true
break
}
fmt.Printf("k---%d j---%d\n", k, j)
}
//退出外层for
if flag {
break
}
}
}
func main() {
gotoDemo()
}
goto优化版
package main
import "fmt"
func gotoDemo() {
var flag bool
//如何一次性退出 所有嵌套的for?
for k := 0; k < 10; k++ {
for j := 0; j < 10; j++ {
//期望到2的时候退出所有for
if j == 2 {
//单独一个break只能退出当前for
flag = true
break
}
fmt.Printf("k---%d j---%d\n", k, j)
}
//退出外层for
if flag {
break
}
}
}
func gotoDemo2() {
for k := 0; k < 10; k++ {
for j := 0; j < 10; j++ {
//期望到2的时候退出所有for
if j == 2 {
//goto无条件,直接跳转到指定代码处
goto breakTag
}
fmt.Printf("k---%d j---%d\n", k, j)
}
}
breakTag:
fmt.Println("已进入goto区域")
}
func main() {
gotoDemo2()
}
break结束循环
break可以结束for、switch、select的代码块。
break也支持在语句后写标签,表示退出某标签对应的代码块。
常见用法
package main
import "fmt"
func main() {
var num int = 0
for num < 20 {
fmt.Printf("a的值是:%v\n", num)
num++
if num > 15 {
break //跳出for循环
}
}
}
break label特性
package main
import "fmt"
func breakDemo1() {
breakFlag:
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j == 2 {
break breakFlag
}
fmt.Printf("%v-%v\n", i, j)
}
}
fmt.Println("所有for循环已结束")
}
func main() {
breakDemo1()
}
continue跳出本次循环
continue语句跳出当前循环剩余代码,继续进行下一次循环,仅限于在for循环内使用。
package main
import "fmt"
func main() {
/* for 循环 */
for a := 10; a < 20; {
if a == 15 {
/* 当a等于15时,跳出循环,让a++,等于16,跳过本次循环 */
a++
continue
}
fmt.Printf("a 的值为 : %d\n", a)
a++
}
}
continue label特性
无须了解
package main
import "fmt"
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\n", i, j)
}
}
}
func main() {
continueDemo()
}
return语句
return用在方法或函数中,表示终止所在的方法或函数(method与function)。
return在main函数中,表示终止main函数,终止程序。
package main
import "fmt"
func main() {
for i := 0; i <= 10; i++ {
if i == 5 {
return //直接退出main函数了
}
fmt.Printf("本次循环次数:%d\n", i)
}
//永远走不带这里了,第五次for循环时候,直接return了
fmt.Println("我会被执行吗????")
}
普通函数
package main
import "fmt"
func returnDemo() {
for i := 0; i <= 10; i++ {
if i == 5 {
return //
}
fmt.Printf("本次循环次数:%d\n", i)
}
}
func main() {
returnDemo()
fmt.Println("程序已结束")
}
Go基础小结
1.go环境部署
1. 安装go环境,官网下载即可,配置PATH变量
2. 设置GOPATH,使用go env查看
3. 安装go代码编辑器,vscode,或者goland
2.变量
1. 变量是什么,go定义变量的规则,数据类型设置,如何赋值
2. 匿名变量,下划线 _
3. go变量命名风格,建议驼峰体
3.常量
1. 不可修改的常量
2. iota常量生成器
4.基础数据类型
1. 字符串
2. 整型、浮点数、复数
3. 布尔值
4. 字符类型(单引号)、rune、byte
5.运算符
6.流程控制
1. if ...else if ... else
2. for for ...range
3. switch ..case
4. goto/continue/break/return
7.go语法细节
1. 变量声明后必须使用(局部变量),全局变量可以不用
2. ...
8.go 程序管理
1. go.mod作用是保存当前项目的依赖信息
- go编译器版本
- 所有依赖包的名字、版本
2. go package
作为可以go build编译的源码程序,必须有一个 package main ,以及 func main(){} 入口函数
3. go build、以及go run
go run main.go // go自动在一个临时文件夹,先build,然后再执行程序
go build main.go // 编译源文件,生成可执行的二进制程序
go build -o xxx.exe (windows)
go build -o xxx (unix)
4.交叉编译
# windows使用set,linux不需要
SET CGO_ENABLED=0
SET GOOS=darwin/windows/linux
SET GOARCH=amd64
go build
9.go包管理
1. go如何引入别人的源码库,以及函数调用
2. 如何执行多个go源码文件,建议go build,而不是go run(否则你得 go run main.go a.go b.go c.go)