程序的流程控制结构一共有三种:顺序结构,选择结构,循环结构
顺序结构:从上到下,逐行执行。默认的逻辑
选择结构:条件满足某些代码才会执行
if
switch
select,后面 channel 再讲
循环结构:条件满足某些代码会被反复执行0-N次
for
Go 语言条件语句
条件语句需要开发者通过指定一个或多个条件,并通过测试条件是否为true来决定是否执行指定语句,并在条件为false的情况在执行另外的语句。
下图展示了程序语言中条件语句的结构:
Go 语言提供了以下几种条件判断语句:
if语句,if...else 语句
if 语句 由一个布尔表达式后紧跟一个或多个语句组成。
if 语句 后可以使用可选的 else 语句, else 语句中的表达式在布尔表达式为 false 时执行。
if 或 else if 语句中可嵌入一个或多个 if 或 else if 语句。
同各类主流语言,不多赘述。但注意,Go 没有三目运算符,所以不支持 ?: 形式的条件判断
//if else语句
package main
import "fmt"
func main() {
// 定义一个整数变量
var number int
fmt.Print("请输入一个整数: ")
fmt.Scanln(&number)
// 使用 if 语句判断成绩等级
if number >= 90 && number <= 100 {
fmt.Println("成绩优秀")
}else if number >= 80 && number < 90 {
fmt.Println("成绩良好")
}else if number >= 70 && number < 80 {
fmt.Println("成绩中等")
}else if number >= 60 && number < 70 {
fmt.Println("成绩及格")
}else{
fmt.Println("成绩不及格")
}
/*// 使用 if 语句判断数字的奇偶性
if number%2 == 0 {
fmt.Printf("%d 是偶数\n", number)
} else {
fmt.Printf("%d 是奇数\n", number)
}
// 使用 if-else 语句判断数字的正负性
if number > 0 {
fmt.Printf("%d 是正数\n", number)
} else if number < 0 {
fmt.Printf("%d 是负数\n", number)
} else {
fmt.Println("输入的数字是零")
}*/
}
if嵌套语句
实例一:
// if 嵌套语句
package main
import "fmt"
func main() {
var a int = 100
var b int = 201
if a == 100 {
fmt.Println("a满足条件,a的值为100")
if b == 200 {
fmt.Println("b满足条件,b的值为200")
}
}
}
实例二:
// if 嵌套语句(双重验证密码,并验证用户角色)
package main
import "fmt"
func main() {
var a, b string
var pwd string = "Yang@001025"
// 用户输入
fmt.Print("请输入密码: ")
fmt.Scanln(&a)
// 业务:验证密码是否正确
if a == pwd {
fmt.Println("请再次输入密码:")
fmt.Scanln(&b)
if b == pwd {
fmt.Println("密码验证成功,欢迎进入系统!")
} else {
fmt.Println("第二次密码与第一次不一致,请重新输入:")
}
// 密码正确后,验证用户角色
var role string
fmt.Print("请输入角色(admin/user):")
fmt.Scanln(&role)
switch role {
case "admin":
fmt.Println("欢迎管理员!您可以进行所有操作。")
case "user":
fmt.Println("欢迎用户!您可以进行基本操作。")
default:
fmt.Println("角色不正确,请重新输入。")
}
} else {
fmt.Println("密码错误,请重新输入。")
}
}
switch语句
用于基于不同条件执行不同动作,每一个 case 分支都是唯一的,从上至下逐一测试,直到匹配为止。
匹配项后面不需要再加 break。
switch 默认情况下 case 最后自带 break 语句,匹配成功后就不会执行其他 case,如果我们需要执行后面的 case,可以使用 fallthrough 。
fallthrough:强制执行后面的 case 语句,fallthrough 不会判断下一条 case 的表达式结果是否为 true
实例一:
package main
import "fmt"
func main() {
// 定义一个整数变量
var number int
fmt.Print("请输入一个整数: ")
fmt.Scanln(&number)
// 使用 switch 语句判断成绩等级
switch {
case number >= 90 && number <= 100:
fmt.Println("成绩优秀")
case number >= 80 && number < 90:
fmt.Println("成绩良好")
case number >= 70 && number < 80:
fmt.Println("成绩中等")
case number >= 60 && number < 70:
fmt.Println("成绩及格")
default:
fmt.Println("成绩不及格")
}
// switch 默认的条件为 true
switch {
case false:
fmt.Println("false分支")
case true:
fmt.Println("true分支")
default:
fmt.Println("默认分支")
}
}
fallthrough 贯穿;直通
switch默认情况下匹配成功后就不会执行其他case,如果我们需要执行后面的case,可以使用fallthrough穿透case使用fallthrough会强制执行后面的case语句,fallthrough不会判断下一条case的表达式结果是否为true。
实例一:
package main
import "fmt"
func main() {
a := false
switch a {
case false:
fmt.Println("a is false")
fallthrough // 执行完当前 case 后继续执行下一个 case
case true:
/*if a == false {
break // 如果 a 是 false,则跳出 switch 语句
}*/
fmt.Println("a is true")
default:
fmt.Println("a is neither true nor false")
}
}
实例二:
package main
import "fmt"
func main() {
// 定义一个整数变量
var number int
fmt.Print("请输入一个整数: ")
fmt.Scanln(&number)
// 使用 switch 语句判断成绩等级
switch {
case number >= 90 && number <= 100:
fmt.Println("成绩优秀")
fallthrough // 执行完当前 case 后继续执行下一个 case
case number >= 80 && number < 90:
fmt.Println("成绩良好")
fallthrough
case number >= 70 && number < 80:
/*if number >= 75 {
break // 如果成绩大于等于 75,跳出 switch 语句
}*/
fmt.Println("成绩中等")
fallthrough
case number >= 60 && number < 70:
fmt.Println("成绩及格")
fallthrough
default:
fmt.Println("成绩不及格")
}
}
select语句
每个 case 都必须是一个通信
所有 channel 表达式都会被求值
所有被发送的表达式都会被求值
如果任意某个通信可以进行,它就执行,其他被忽略。
如果有多个 case 都可以运行,Select 会随机公平地选出一个执行。其他不会执行。 否则:
如果有 default 子句,则执行该语句。
如果没有 default 子句,select 将阻塞,直到某个通信可以运行;Go 不会重新对 channel 或值进行求值。
Go 语言循环语句
在不少实际问题中有许多具有规律性的重复操作,因此在程序中就需要重复执行某些语句。
Go 语言提供了以下几种类型循环处理语句:
for循环
for循环是一个循环控制结构,可以执行指定次数的循环。
package main
import "fmt"
func main(){
// for 给控制变量的值 循环条件 给控制变量、增量或减量。
for i := 1; i <= 5; i ++{
//循环体
fmt.Println("打印次数:", i)
}
}
//另一种写法
i := 1
//如果不写循环条件 i <= 10 程序则会无限打印
for i <= 10{
i ++
fmt.Println("打印次数:", i)
}
例题:计算1到100的数字之和。
package main
import "fmt"
func main() {
// 计算1到100的和
sum := 0
for i := 1; i <= 100; i++ {
sum += i
}
fmt.Println("1到100的和是:", sum)
}
for range循环
package main
import "fmt"
func main() {
str := "hello,world" // 包含中文字符的字符串
// for range循环,遍历数组、切片......
// 返回下标对应的值,使用这个值就可以了
for i, v := range str {
fmt.Print(i)
fmt.Printf("%c", v)
}
}
循环嵌套
例题:打印一个5*5的方阵
/*打印一个5*5的矩形
* * * * * 换行
* * * * *
* * * * *
* * * * *
* * * * *
*/
// L:\goproject\src\go_code\chaoter07\for\demo2\demo2.go"
package main
import "fmt"
func main() {
//打印一个5*5的矩形
for i := 1; i <= 5; i++ {
// 循环嵌套
// 内层循环控制每行打印的星号数量
// 外层循环控制行数
for j := 1; j <= 5; j++ {
fmt.Print("* ")
}
fmt.Println() // 换行
}
}
例题二:使用for循环打印99乘法表
// L:\goproject\src\go_code\chaoter07\for\demo3\demo3.go"
package main
import "fmt"
func main() {
// 使用for循环打印99乘法表
for i := 1; i <= 9; i++ {
// 内层循环控制每行打印的乘法表
// 外层循环控制行数
// 例如:第一行打印1*1=1,第二行打印1*2=2, 2*2=4,第三行打印1*3=3, 2*3=6, 3*3=9
// 依次类推
for j := 1; j <= i; j++ {
fmt.Printf("%d * %d = %d\t", j, i, i*j)
}
fmt.Println() // 换行
}
}
循环控制语句
循环控制语句可以控制循环体内语句的执行过程。
GO 语言支持以下几种循环控制语句:
break语句:
用于循环语句中跳出循环,并开始执行循环之后的语句。
break 在 switch(开关语句)中在执行一条 case 后跳出语句的作用。
在多重循环中,可以用标号 label 标出想 break 的循环。
continue语句:跳过当前循环的剩余语句,然后继续进行下一轮循环。
goto:无条件转移到过程中指定行,与条件语句配合,实现条件转移、构成循环、跳出循环体等(不建议用,造成混乱)
break 结束当前整个循环
package main
import "fmt"
func main() {
for i := 1; i <= 10; i++{
if i == 4{
break
}
fmt.Println(i)
}
}
continue 结束当次循环
package main
import "fmt"
func main() {
for i := 1; i <= 10; i++{
if i == 4{
continue
}
fmt.Println(i)
}
}
string类型
什么是string
Go中的字符串是一个字节的切片,可以通过将其内容封装在""中来创建字符串,Go中的字符串是Unicode兼容的,并且是UTF-8编码。
字符串是一些字节的集合。
package main
import "fmt"
func main() {
str := "hello,world" // 包含中文字符的字符串
// Go中的字符串是UTF-8编码的,可以直接包含中文字符
fmt.Println(str)
// 获取字符串的长度
// 注意:len函数返回的是字节数,而不是字符数
// 对于UTF-8编码的字符串,中文字符通常占用3个字符
fmt.Println("字符串长度:", len(str))
// 获取指定的字符
fmt.Println("ASCII编码为:", str[0]) // 输出第一个字符的ASCII编码,(有大小写区分)
fmt.Println(string(str[0])) // 将ASCII编码转换为字符
fmt.Printf("%c\n", str[0]) // 将ASCII编码转换为字符
// 遍历字符串中的每个字符对应的ASCII编码
for i := 0; i < len(str); i++ {
fmt.Printf("字符: %c, ASCII编码: %d\n", str[i], str[i])
}
}