【GO语言】流程控制语句

一、if 语句

 IF 语句书写格式

  • 如果逻辑表达式成立,执行{}里的内容
  • 逻辑表达式不需要加()
  • “{” 必须紧跟在逻辑表达式之后,不能另起一行
  • 变量赋值语句允许同时初始化多个局部变量
  • 逻辑表达式中可以含有变量和常量
  • if 语句中仅允许包含1个分号,在分号前初始化一些局部变量(仅在该 if 块内可见)
  • else if 允许拥有 0个、1个、多个
  • else 允许拥有 0个 或 1个
  • else if 和 else 书写格式都必须跟在上一个语句块 “}” 之后,不允许另起一行
    if 变量赋值语句 ; 逻辑表达式 {
        执行代码语句块
    } else if 逻辑表达式 {
        执行代码语句块
    } else if 逻辑表达式 {
        执行代码语句块
    } else {
        执行代码语句块
    }

范例:

func main() {
    if a, b, c := 10, 22, 22; a > b && a > c {
        fmt.Println("a is max")
    } else if b > a && b > c {
        fmt.Println("b is max")
    } else if c > a && c > b {
        fmt.Println("c is max")
    } else {
        fmt.Println("I don't kown")
    }
}

输出结果:

   

二、switch 语句

  • switch-case-default 可模拟 if-else if-else,但只能实现相等判断
  • switch 和 case 后面可以跟常量、变量或函数表达式,只要它们表示的数据类型相同就行
  • case后面可以跟多个值,只要有一个值满足就行

 范例:

var color string = "black"

func main() {
    switch color {
    case "red":
        fmt.Println("stopped")
    case "green":
        fmt.Println("running")
    default:
        fmt.Printf("color %s undefined", color)
    }
}

输出结果:

  

 

范例:

var color string = "black"

func main() {
    switch color {
    case "red":
        fmt.Println("stopped")
    case "green":
        fmt.Println("running")
    case "white", "black":
        fmt.Println("faild")
    default:
        fmt.Printf("color %s undefined", color)
    }
}

输出结果:

  

 

空switch

switch后带表达式时,switch-case 只能模拟相等的情况,如果 switch 后不带表达式,case 后可以跟任意的条件表达式

范例:

func a_b(a int, b int) {
    switch {
    case a > b:
        fmt.Println("a is bigger")
    case a < b:
        fmt.Println("b is bigger")
    default:
        fmt.Println("a = b")
    }
}

func main() {
    a_b(10, 20)
    a_b(30, 20)
    a_b(20, 20)
}

输出结果:

  

 

switch Type

用于判断 interface{} 类型,或 interface{} 对应类型的值处理

错误范例:

// 只做类型判断时: 如果对 num 进行数据处理,由于num的类型依旧为 interface{},会禁止进行数据处理
// 可在数据处理前时进行数据格式强制转换后,处理数据  例:func switch_type_value2(){}
func switch_type(num interface{}) {
    switch num.(type) {
    case int:
        fmt.Printf("num type is %T\n", num+1)
    case float64:
        fmt.Printf("num type is %T\n", num)
    case string:
        fmt.Printf("num type is %T\n", num)
    default:
        fmt.Println("num type is others")
    }
}

func main() {
    switch_type(3)
}

输出结果:

 

范例:

// 只做类型判断时: 如果对 num 进行数据处理,由于num的类型依旧为 interface{},会禁止进行数据处理
// 可在数据处理前时进行数据格式强制转换后,处理数据  例:func switch_type_value2(){}
func switch_type(num interface{}) {
    switch num.(type) {
    case int:
        fmt.Printf("num type is %T\n", num)
    case float64:
        fmt.Printf("num type is %T\n", num)
    case string:
        fmt.Printf("num type is %T\n", num)
    default:
        fmt.Println("num type is others")
    }
}

// 进行类型判断并且需要调用interface{} 值时:会在 case type 字段将 value 进行类型转换,因此可以直接进行数据处理
// 等价于 func switch_type_value2(){}
func switch_type_value(num interface{}) {
    switch value := num.(type) {
    case int: // 此处 value 已经被强制转换为 int 类型
        fmt.Printf("num type is %T,\tnum+1 = %d\n", value, value+1)
    case float64: // 此处 value 已经被强制转换为 float64 类型
        fmt.Printf("num type is %T,\tnum+3.4 = %.1f\n", value, value+3.4)
    case string: // 此处 value 已经被强制转换为 string 类型
        fmt.Printf("num type is %T,\tnum+'abc' = %s\n", value, value+"abc")
    case byte, rune: // 当出现多个类型时,value 依旧保持 interface{} 类型
        fmt.Printf("num type is %T\n", value)
    default:
        fmt.Printf("num type is others,num = %v\n", value)
    }
}

// 此函数等价于 func switch_type_value(){}
func switch_type_value1(num interface{}) {
    switch num.(type) {
    case int:
        value := num.(int)
        fmt.Printf("num type is %T,\tnum+1 = %d\n", value, value+1)
    case float64:
        value := num.(float64)
        fmt.Printf("num type is %T,\tnum+2.2 = %.1f\n", value, value+2.2)
    case string:
        value := num.(string)
        fmt.Printf("num type is %T,\tnum+'abc' = %s\n", value, value+"abc")
    default:
        fmt.Println("num type is others")
    }
}

func main() {
    fmt.Println("swtich_type--------------------------")
    switch_type(3.1)
    switch_type(3)
    switch_type("3")
    fmt.Println("swtich_type_value--------------------------")
    switch_type_value(3.2)
    switch_type_value(3)
    switch_type_value("3")
    fmt.Println("swtich_type_value1--------------------------")
    switch_type_value1(3.2)
    switch_type_value1(3)
    switch_type_value1("3")
}

输出结果:

  

 

fallthrough

  • 从上往下,只要找到成立的case,就不再执行后面的 case 了。所以为了提高性能,把大概率会满足的情况往前放
  • case 里如果带了 fallthrough ,则执行完本 case 代码内容 不执行条件判断,强制执行下一个 case 代码内容
  • 在 switch Type 语句的 case 子句中不能使用 fallthrough

范例(未使用fallthrough,语句成功匹配到 case 后续的 case default 内容直接跳过):

func user_permission(level int) {
    fmt.Printf("用户等级 %d, 开放以下权限:", level)
    switch {
    case level >= 100:
        fmt.Printf("勋章\n")
    case level >= 70:
        fmt.Printf("交易\n")
    case level >= 50:
        fmt.Printf("师徒\n")
    case level >= 30:
        fmt.Printf("排位\n")
    case level >= 10:
        fmt.Println("商城\n")
    case level < 10:
        fmt.Println("未达到10级,无任何权限\n")

    }
}

func main() {
    user_permission(180)
    user_permission(91)
    user_permission(70)
    user_permission(7)
}

输出结果:

  

 

范例(使用 fallthrough 导致后续 case 被强制执行):

func user_permission(level int) {
    fmt.Printf("用户等级 %d, 开放以下权限:", level)
    switch {
    case level >= 100:
        fmt.Printf("勋章 ")
        fallthrough
    case level >= 70:
        fmt.Printf("交易 ")
        fallthrough
    case level >= 50:
        fmt.Printf("师徒 ")
        fallthrough
    case level >= 30:
        fmt.Printf("排位 ")
        fallthrough
    case level >= 10:
        fmt.Println("商城")
        fallthrough  // 由于此处执行了 fallthrough , 下一个 case level < 10 会忽略判断结果强制执行
    case level < 10:
        fmt.Println("未达到10级,无任何权限")

    }
}

func main() {
    user_permission(180)
    user_permission(91)
    user_permission(70)
    user_permission(7)
}

 输出结果:

  

 

范例(合理使用 fallthrough):

func user_permission(level int) {
    fmt.Printf("用户等级 %d, 开放以下权限:", level)
    switch {
    case level >= 100:
        fmt.Printf("勋章 ")
        fallthrough
    case level >= 70:
        fmt.Printf("交易 ")
        fallthrough
    case level >= 50:
        fmt.Printf("师徒 ")
        fallthrough
    case level >= 30:
        fmt.Printf("排位 ")
        fallthrough
    case level >= 10:
        fmt.Println("商城")
    case level < 10:
        fmt.Println("未达到10级,无任何权限")

    }
}

func main() {
    user_permission(180)
    user_permission(91)
    user_permission(70)
    user_permission(7)
}

输出结果:

  

 

三、for 循环

  •  FOR 语句书写格式:
  • 逻辑表达式成立,执行{}中的内容,{}内容执行完毕执行后续操作
  • 局部变量只作用于当前 for 语句块
  • 初始化的变量可以放在 for 语句上面(此时不再仅作为当前 for 语句的局部变量)
  • 后续操作可以放在 for 内部
  • 只有条件判断时,前后的分号可以省略
  • for {} 是一个无限循环
  • 变量赋值语句、逻辑表达语句、后续操作可以同时处理多个值
for 变量赋值语句 ; 逻辑表达式; 后续操作 {
    执行代码语句块
}

范例:

func for_deined() {
    arr := [...]int{1, 7, 9, 5, 6}

    // 格式1
    fmt.Println("formate 1 ===================")
    for i := 0; i < len(arr); i++ {
        fmt.Println(arr[i])
    }

    // 格式2
    fmt.Println("formate 2 ===================")
    for i := 0; i < len(arr); {
        fmt.Println(arr[i])
        i++
    }

    // 格式3
    fmt.Println("formate 3 ===================")
    {
        i := 0
        for i < len(arr) {
            fmt.Println(arr[i])
            i++
        }
    }
}

func main() {
    for_deined()
}

输出结果:

  

范例:

func for_deined2() {
    for i, sum := 1, 1; i < 10 && sum < 100; i, sum = i+1, sum*i {
        fmt.Printf("i = %d\t sum = %d\n", i, sum)
    }

}

func main() {
    for_deined2()
}

输出结果:

  

 

 for range

  • 遍历数组或切片
  • 遍历string
  • 遍历map,不保证遍历顺序
  • 遍历channl,需要提前 close
  • for range 拿到的是数据值拷贝
// 遍历数组或切片
for i,ele := range arr {}

// 遍历string(汉字占用3个字节)
for i,ele := range "这是一个string" {}  // ele 是一个 rune

// 遍历map
for key,value := range m {}

// 遍历channl
for ele := range ch {}

 

 

四、break 和 continue 语句

  • break 和 continue 用于控制 for 循环的代码流程,并且只针对所在最近的 for 循环生效(当前所在的 for 代码语句块)
  • break: 退出 for 循环,且本轮 break 后面的代码不再执行
  • continue: 本轮 continue 后面的代码不再执行,进入下一轮的 for 循环

 

五、goto 与 Label 语句

  • 可以通过使用 goto label 语句更加灵活的控制语句流程
  • label 定义位置没有限制,可以在 goto 调用之前定义,也可以在 goto 调用之后定义,但是已经定义的 label 必须在某个地方被调用
  • goto label 跳转到 定义的 label 之后一行开始运行代码

    

package main

import "fmt"

func echo_page(page int, size int, arr []int) {
    start := (page - 1) * size
    end := page * size
    if len(arr) < end {
        end = len(arr)
    }
    for _, v := range arr[start:end] {
        fmt.Printf("%d\t", v)
    }
}

func main() {
    arr := []int{23, 42, 21, 3, 4, 5, 62, 13, 4, 2, 34, 1, 3, 14, 14, 13, 31, 41}
    arr_len := len(arr)
    page := 0
    size := 5
L1:
    page++
    echo_page(page, size, arr)
    fmt.Printf("\n")
    if arr_len > page*size {
        goto L1
    }

}

continue Label 与 break Label

continue 与 break 也可以与 Label 结合使用,可以实现跳转到更外层的 for 循环

continue 与 break 调用的 Label 必须写在语句所在 for 循环体以外,goto Label 可以针对任意位置

范例:

// 等价于 func continue_1() {}
func continue_label_1() {
    arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    brr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}

    for _, a := range arr {
    L1:
        for _, b := range brr {
            if a == b {
                fmt.Printf("%d*%d=%d\n", a, b, a*b)
                continue L1
            }
            fmt.Printf("%d*%d=%d\t", a, b, a*b)

        }

    }
}

func continue_1() {
    arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    brr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}

    for _, a := range arr {
        for _, b := range brr {
            if a == b {
                fmt.Printf("%d*%d=%d\n", a, b, a*b)
                continue
            }
            fmt.Printf("%d*%d=%d\t", a, b, a*b)

        }

    }
}

// 实现continue跳出上一层循环
func continue_label_2() {
    arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
    brr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
L1:
    for _, a := range arr {
        for _, b := range brr {
            if a == b {
                fmt.Printf("%d*%d=%d\n", a, b, a*b)
                continue L1  // break
            }
            fmt.Printf("%d*%d=%d\t", a, b, a*b)

        }

    }
}

func main() {
    continue_label_1()
    fmt.Println("==========================================================")
    continue_label_2()

}

 输出结果:

 

 

posted @ 2023-08-02 00:01  Janzen_Q  阅读(17)  评论(0编辑  收藏  举报