程序的流程控制结构一共有三种:顺序结构,选择结构,循环结构

顺序结构:从上到下,逐行执行。默认的逻辑

选择结构:条件满足某些代码才会执行

  • if

  • switch

  • select,后面 channel 再讲

循环结构:条件满足某些代码会被反复执行0-N次

  • for

Go 语言条件语句

条件语句需要开发者通过指定一个或多个条件,并通过测试条件是否为true来决定是否执行指定语句,并在条件为false的情况在执行另外的语句。

下图展示了程序语言中条件语句的结构:

image-20250704164018485

Go 语言提供了以下几种条件判断语句:

语句

描述

if 语句

if 语句 由一个布尔表达式后紧跟一个或多个语句组成。

if...else 语句

if 语句 后可以使用可选的 else 语句, else 语句中的表达式在布尔表达式为 false 时执行。

if 嵌套语句

你可以在 ifelse if 语句中嵌入一个或多个 ifelse if 语句。

switch 语句

switch 语句用于基于不同条件执行不同动作。

select 语句

select 语句类似于 switch 语句,但是select会随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。

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 会随机公平地选出一个执行。其他不会执行。 否则:

    1. 如果有 default 子句,则执行该语句。

    2. 如果没有 default 子句,select 将阻塞,直到某个通信可以运行;Go 不会重新对 channel 或值进行求值。

Go 语言循环语句

在不少实际问题中有许多具有规律性的重复操作,因此在程序中就需要重复执行某些语句。

image-20250704182457397

Go 语言提供了以下几种类型循环处理语句:

循环类型

描述

for 循环

重复执行语句块

循环嵌套

在 for 循环中嵌套一个或多个 for 循环

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 语句

经常用于中断当前 for 循环或跳出 switch 语句

continue 语句

跳过当前循环的剩余语句,然后继续进行下一轮循环。

goto 语句

将控制转移到被标记的语句。

  • 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])
    }
}