zoukankan      html  css  js  c++  java
  • <7>Golang基础进阶——流程控制

    Golang开发之流程控制

    1. 条件判断(if)

    Go语言if条件判断格式如下:

    if 表达式1 {
    分支1
    } else if 表达式2 {
    分支2
    } else {
    分支3
    }

    Go 规定与 if 匹配的左括号 “{” 必须与 if 和表达式放在同一行,如果尝试将“{”放在其它位置,将会触发编译错误,同理else也是。

    举例:

    var ten int = 11

    if ten > 10 {
    fmt.Println(">10")
    } else {
    fmt.Println("<=10")
    }

    特殊写法:

    可以在if表达式之前添加一个执行语句,再根据变量值进行判断:

    if err := Connect(); err != nil {
    fmt.Println(err)
    return
    }

    err != nil 才是 if 的判断表达式,当 err 不为空时,打印错误并返回。

     

    2. 构建循环(for)

    for 循环格式如下:

    for 初始语句;条件表达式;结束语句{
    循环体代码
    }

    结束语句为最后执行。

    2.1. for 中的初始语句一一开始循环时执行的语句

    初始语句是在第一次循环前执行的语句,其作用域将被局限在这个for的范畴内。
    初始语句可以被忽略,但是初始语句之后的分号必须要写:

    step := 2
    for ; step > 0; step-- {
    fmt.Println(step)
    }

    这段代码for中没有初始语句,此时step的作用域就比在初始语句声明step要大。

    2.2. for 中的条件表达式-一控制是否循环的开关

    2.2.1. 结束循环时带可执行语句的无限循环
    var i int
    for ; ; i++ {
    if i > 10 {
    break
    }
    }

    2.2.2. 无限循环

    var i int
    for {
    if i > 10 {
    break
    }
    i++
    }
    2.2.3. 只有一个循环条件的循环
    var i int

    for i <= 10{
    i++
    }

     

    3. 示例:九九乘法口诀表

    for y := 1; y <= 9; y++ {
    for x := 1; x <= y; x++ {
    fmt.Printf("%d * %d = %d ", x, y, x*y)

    }
    fmt.Println()
    }

     4. 键值循环( for range )一一直接获得

    Go 语言可以使用 for range 遍历数组、切片、 字符串 map 及通道( channel )。通过 for range 遍历的返回值有一定的规律:

    • 数组、切片、字符串返回索引和值。
    • map返回键和值。
    • 通道(channel)只返回通道内的值。

    4.1.  遍历数组、切片一一获得索引和元素

    在遍历代码中, key value 分别代表切片的下标、下标对应的值。

    func main() {
    for key, value := range []int{1,2,3,4} {
    fmt.Printf("key:%d value:%d ", key, value)
    }

    }
    //代码输出如下:
    //key : 0 value:1
    //key : 1 value:2
    //key : 2 value:3
    //key : 3 value:4

    4.2. 遍历字符串一一获得字符

    key value 分别代表字符串的索引 (base0)和字符串中的每一个字符。

    func main() {
    var str = "hello 你好"
    for key, value := range str {
    fmt.Printf("key:%d valye:0x%x ", key, value)
    }

    }
    //key : 0 value : Ox68
    //key : 1 value : Ox65
    //key : 2 value : Ox6c
    //key : 3 value : Ox6c
    //key : 4 value : Ox6f
    //key : 5 value : Ox20
    //key : 6 value : Ox4f60
    //key : 9 value : Ox597d

    代码中的v变量,实际类型是rune,实际上就是 int32 ,以十六进制打印出来就是字符的编码。

    4.3. 遍历 map一一一获得 map 的键和值

    对于 map 类型来说,for range 遍历时, key value 分别代 map 的索引键 key 和索引对应的值。

    func main() {
    m := map[string]int{
    "hello":100,
    "world":200,
    }

    for key, value := range m {
    fmt.Println(key, value)
    }

    }
    //代码输出如下
    //hello 100
    //world 200

    注意: 遍历时,遍历输出的键值是无序的,如果需要有序的键值对输出,需要对结果进行排序

    4.4. 遍历通道 channel 一一接收通道数据

    for range 可以遍历通道(channel) ,但通道在遍历时,只输出一个值,即管道内的对应的数据。

    func main() {
    c := make(chan int)

    go func (){
    c <- 1
    c <- 2
    c <- 3
    close(c)
    }()

    for v := range c{
    fmt.Println(v)
    }

    }
    //代码输出如下
    //1
    //2
    //3

    4.5. 在遍历中选择希望获得的变量

    使用 for range 循环遍历某个对象一般不会同时需要key 或者 value

    func main() {
    m := map[string]int{
    "world" : 100,
    "hello" : 200,
    }

    for _, value := range m{
    fmt.Println(value)
    }

    }
    //代码输出如下
    //100
    //200

    本身这种变量不会进行空间分配,也不会占用一个变量的名字。
    在for range 可以对 key 使用匿名变量,也可以对 value 用匿名变量。

     5. 分支选择( switch )一一拥青多个条件分支的判断

    分支选择可以理解为一种批量的 if 语句 ,使用 switch 语句可方便地对大量的值进行判断。

    5.1. 基本写法

    func main() {
    var a ="hello"
    switch a{
    case "hello":
    fmt.Println(1)
    case "world":
    fmt.Println(2)
    default:
    fmt.Println(0)
    }

    }
    // 代码输出如下:
    // 1

    上面例子中,每个case 均是字符串格式,且使用了 default 分支, Go规定定每个switch 只能有一个 default 分支。

    5.1.1. 一分支多值
    func main() {
    var a = "num"
    switch a {
    case "mum", "daddy":
    fmt.Println("family")
    }
    }

    不同的 case 表达式使用逗号分隔。

    5.1.2. 分支表达式

    case 后不仅仅只是常量, 还可以和if一样添加表达式:

    func main() {
    var r int = 11
    switch {
    case r > 10 && r<20:
    fmt.Println(r)
    }
    }
    5.1.3. 跨越 case 的 fallthrough 兼容C语言的 case 设计

    在 Go 语言中 case 是一个独立的代码块,执行完毕后不会像C语言那样紧接着下一个 case 执行。但是为了兼容一些移植代码,依然加入了 fallthrough 关键字来实现这一功能,代码如下:

    func main() {
    var s = "hello"
    switch {
    case s == "hello":
    fmt.Println("hello")
    fallthrough
    case s != "world":
    fmt.Println("world")

    }

    }
    // 代码输出如下
    // hello
    // world

    新编写的代码,不建议使用 fallthrough。

     6. 跳转到指定代码标签(goto)

    goto 语句通过标签进行代码间的无条件跳转。 goto 语句可以在快速跳出循环、避免重复退出。 Go 语言中使用 goto 语句能简化一些代码的实现过程。

    6.1 使用goto退出多层循环

    下面这段代码在满足条件时,需要连续退出两层循环,使用传统的编码方式如下:

    func main() {
    var breakAgain bool

    // 外循环
    for x:=0; x<10;x++{
    //内循环
    for y :=0;y<10;y++{
    // 满足某个条件时,退出循环
    if y == 2 {
    // 设置退出标记
    breakAgain = true

    // 退出本次循环
    break
    }
    }
    if breakAgain {
    break
    }
    }
    fmt.Println("done")
    }

    将代码进行goto优化:

    func main() {

    // 外循环
    for x := 0; x < 10; x++ {
    //内循环
    for y := 0; y < 10; y++ {
    // 满足某个条件时,退出循环
    fmt.Println(y)
    if y == 2 {
    // 跳转标签

    goto breakHere
    }
    }
    // 手动返回,避免执行进入标签
    return
    }
    breakHere:
    fmt.Println("done")

    }

    return如果不手动返回在不满足条件时,breakHere 也会执行代码

    6.2 统一错误处理

    多处错误处理存在代码重复时是非常棘手的 ,例如

    func main() {

    err := fiirstCheckError()
    if err != nil {
    fmt.Println(err)
    exitProcess()
    return
    }

    err = secondCheckError()
    if err != nil {
    fmt.Println(err)
    exitProcess()
    return
    }
    fmt.Println("done")

    }

    如果使用 goto 语句来实现同样的逻辑:

    func main() {
    err := fiirstCheckError()
    if err != nil {
    goto onExit
    }

    err = secondCheckError()
    if err != nil {
    goto onExit
    }

    fmt.Println("done")
    return

    onExit:
    fmt.Println(err)
    exitProcess()

    }

     

    7. 跳出指定循环( break )一一可以跳出多层循环 

    break 语句还可以在语句后面添加标签,表示退出某个标签对应的代码块,标签要求必须定义在对应的 for、switch、select 的代码块上。

    func main() {
    OuterLoop:
    for i := 0; i < 2; i++ {
    for j := 0; j < 5; j++ {
    switch j {
    case 2:
    fmt.Println(i, j)
    break OuterLoop
    case 3:
    fmt.Println(i, j)
    break OuterLoop

    }
    }
    }
    }

     

    8. 继续下一次循环(continue)

    continue 语句可以结束当前循环, 开始下一次的循环法代过程, 仅限在 for 循环用。在 continue 语句后添加标签时 表示开始标签对应的循环。

    func main() {
    OuterLoop:
    for i := 0; i < 2; i++ {
    for j := 0; j < 5; j++ {
    switch j {
    case 2:
    fmt.Println(i, j)
    continue OuterLoop
    }
    }
    }
    }
    加油,你们是最棒的!
  • 相关阅读:
    SQL Server 执行参数化脚本时的一个性能问题
    2021 年终总结
    循序渐进——NAnt构建实例
    用C#实现单链表(创建单链表,在头部插入)
    用C#实现单链表(插入,在第i个前插,在第i个后插)
    用C#实现单链表(merge两个有序单链表)
    用C#实现单链表(取第i个结点元素,删除第i个结点)
    播放器03:以文件夹的形式添加整个文件夹里面的文件到播放列表,播放刚加进来的第一首歌曲,默认顺序播放
    用C#实现单链表(初始化数据,返回链表元素个数)
    ObjectiveC中创建单例方法的步骤
  • 原文地址:https://www.cnblogs.com/Wshile/p/12681185.html
Copyright © 2011-2022 走看看