• 5、Go语言基础之流程控制


    流程控制是每种编程语言控制逻辑走向和执行次序的重要部分,流程控制可以说是一门语言的“经脉”。

    Go语言中最常用的流程控制有iffor,而switchgoto主要是为了简化代码、降低重复代码而生的结构,属于扩展类的流程控制。

    1、if else(分支结构)

    1.1、if条件判断基本写法

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

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

    当表达式1的结果为true时,执行分支1,否则判断表达式2,如果满足则执行分支2,都不满足时,则执行分支3。 if判断中的else ifelse都是可选的,可以根据实际需要进行选择。

    Go语言规定与if匹配的左括号{必须与if和表达式放在同一行,{放在其他位置会触发编译错误。 同理,与else匹配的{也必须与else写在同一行,else也必须与上一个ifelse if右边的大括号在同一行。

    举个例子:

    package main
    
    import "fmt"
    
    func main() {
    	age := 18				//age变量作用于全局作用域中
    	if age >= 90 {
    		fmt.Println("A")
    	} else if age > 40 {
    		fmt.Println("B")
    	} else {
    		fmt.Println("C")
    	}
    }
    >>>C
    

    1.2、if条件判断特殊写法

    if条件判断还有一种特殊的写法,可以在 if 表达式之前添加一个执行语句,再根据变量值进行判断,举个例子:

    package main
    
    import "fmt"
    
    func main() {
    	if age := 35; age >= 18 {//age只作用于if局部作用域中,if之外无法使用age变量(不存在)
    		fmt.Println("A")
    	} else if age > 75 {
    		fmt.Println("B")
    	} else {
    		fmt.Println("C")
    	}
    }
    >>>A 
    

    注意: 以上两种if写法的区别在于变量值作用域不同。

    2、for(循环结构)

    Go 语言中的所有循环类型均可以使用for关键字来完成(Go语言中只有for循环,没有while循环)。

    for循环的基本格式如下:

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

    条件表达式返回true时循环体不停地进行循环,直到条件表达式返回false时自动退出循环。

    func forDemo() {
    package main
    
    import "fmt"
    
    func main() {
    	for i := 10; i > 0; i-- {
    		fmt.Println(i)
    	}
    }
    >>>
    10
    9
    8
    7
    6
    5
    4
    3
    2
    1
    

    for循环的初始语句可以被忽略,但是初始语句后的分号必须要写,例如:

    package main
    
    import "fmt"
    
    func main() {
    	i := 10
    	for ; i > 0; i-- {
    		fmt.Println(i)
    	}
    }
    >>>
    10
    9
    8
    7
    6
    5
    4
    3
    2
    1
    

    for循环的初始语句和结束语句都可以省略,例如:

    package main
    
    import "fmt"
    
    func main() {
    	i := 10
    	for i > 0 {
    		fmt.Println(i)
    		i--
    	}
    }
    >>>
    10
    9
    8
    7
    6
    5
    4
    3
    2
    1
    

    这种写法类似于其他编程语言中的while,在while后添加一个条件表达式,满足条件表达式时持续循环,否则结束循环。

    2.1、无限循环

    for {
        循环体语句
    }
    

    for循环可以通过breakgotoreturnpanic语句强制退出循环。

    2.2、for range(键值循环)

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

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

    2.3、switch case

    使用switch语句可方便地对大量的值进行条件判断。

    package main
    
    import "fmt"
    
    func main() {
    	num := 3
    	switch num {
    	case 1:
    		fmt.Println("A")
    	case 2:
    		fmt.Println("B")
    	case 3:
    		fmt.Println("C")
    	case 4:
    		fmt.Println("D")
    	case 5:
    		fmt.Println("E")
    	default:
    		fmt.Println("F")
    	}
    }
    >>>C
    

    Go语言规定每个switch只能有一个default分支(条件不满足执行default分支)。

    一个分支可以有多个值,多个case值中间使用英文逗号分隔。

    package main
    
    import "fmt"
    
    func main() {
    	switch n := 8; n {
    	case 1, 3, 5, 7, 9:
    		fmt.Println("单")
    	case 2, 4, 6, 8, 10:
    		fmt.Println("双")
    	default:
    		fmt.Println(n)
    	}
    }
    >>>双
    

    分支还可以使用表达式,这时候switch语句后面不需要再跟判断变量。例如:(不常用)

    package main
    
    import "fmt"
    
    func main() {
    	age := 30
    	switch {
    	case age < 20:
    		fmt.Println("太小")
    	case age >= 20 && age < 35:
    		fmt.Println("努力工作")
    	case age >= 35:
    		fmt.Println("人生转折点")
    	default:
    		fmt.Println("鬼才")
    	}
    }
    >>>鬼才
    

    fallthrough语法可以无条件执行满足当前条件case语句的下一个case语句(不进行判断直接执行),是为了兼容C语言中的case设计的。(不常用)

    package main
    
    import "fmt
    
    func main() {
    	s := "a"  
    	switch {
    	case s == "a":
    		fmt.Println("a")
    		fallthrough
    	case s == "b":
    		fmt.Println("b")
    	case s == "c":
    		fmt.Println("c")
    	default:
    		fmt.Println("d")
    	}
    }
    >>>
    a
    b
    

    2.4、goto(跳转到指定标签)

    goto语句通过标签进行代码间的无条件跳转。goto语句可以在快速跳出循环、避免重复退出上有一定的帮助。Go语言中使用goto语句能简化一些代码的实现过程。 例如双层嵌套的for循环要退出时:

    package main
    
    import "fmt
    
    func main() {
    	flag := false
    	for i := 0; i < 5; i++ {
    		for j := 0; j < 3; j++ {
    			//当i=2,j=2时跳出两层for循环
    			if i == 2 && j == 2 {
    				flag = true
    				break
    			}
    			fmt.Printf("%d--%d
    ", i, j)
    		}
    		//通过标志位来判断是否跳出外层for循环
    		if flag {
    			break
    		}
    	}
    	fmt.Println("两层for循环结束")
    }
    
    >>>
    0--0
    0--1
    0--2
    1--0
    1--1
    1--2
    2--0
    2--1
    两层for循环结束
    

    使用goto语句能简化代码:

    package main
    
    import "fmt"
    
    func main() {
    
    	for i := 0; i < 5; i++ {
    		for j := 0; j < 3; j++ {
    			//当i=2,j=2时跳出两层for循环
    			if i == 2 && j == 2 {
    				goto Label
    
    			}
    			fmt.Printf("%d--%d
    ", i, j)
    		}
    	}
    Label:
    	fmt.Println("两层for循环结束")
    }
    >>>
    0--0
    0--1
    0--2
    1--0
    1--1
    1--2
    2--0
    2--1
    两层for循环结束
    

    2.5、break(跳出循环)

    break语句可以结束forswitchselect的代码块。

    break语句还可以在语句后面添加标签,表示退出某个标签对应的代码块,标签要求必须定义在对应的forswitchselect的代码块上。 举个例子:

    package main
    
    import "fmt"
    
    func main() {
    BREAKDEMO1:
    	for i := 0; i < 10; i++ {
    		for j := 0; j < 10; j++ {
    			if j == 2 {
    				break BREAKDEMO1
    			}
    			fmt.Printf("%v-%v
    ", i, j)
    		}
    	}
    	fmt.Println("两层for循环结束")
    }
    
    >>>
    0-0
    0-1
    两层for循环结束
    

    2.6、continue(继续下次循环)

    continue语句跳出当前循环,开始下一次的循环迭代过程,仅限在for循环内使用。

    continue语句后添加标签时,表示开始标签对应的循环。例如:

    package main
    
    import "fmt"
    
    func main() {
    BREAKDEMO2:
    	for i := 0; i < 5; i++ {
    		// forloop2:
    		for j := 0; j < 5; j++ {
    			if i == 2 && j == 2 {
    				continue BREAKDEMO2
    			}
    			fmt.Printf("%v-%v
    ", i, j)
    		}
    	}
    }
    >>>
    0-0
    0-1
    0-2
    0-3
    0-4
    1-0
    1-1
    1-2
    1-3
    1-4
    2-0
    2-1
    3-0
    3-1
    3-2
    3-3
    3-4
    4-0
    4-1
    4-2
    4-3
    4-4
    

    编写代码打印9*9乘法表

    正序打印:

    package main
    
    import "fmt"
    
    func main() {
    	for i := 1; i < 10; i++ {
    		for j := 1; j <= i; j++ {
    			fmt.Printf("%d*%d=%d	", j, i, i*j)
    		}
    		fmt.Println()
    	}
    }
    >>>
    1*1=1
    1*2=2   2*2=4
    1*3=3   2*3=6   3*3=9
    1*4=4   2*4=8   3*4=12  4*4=16
    1*5=5   2*5=10  3*5=15  4*5=20  5*5=25
    1*6=6   2*6=12  3*6=18  4*6=24  5*6=30  6*6=36
    1*7=7   2*7=14  3*7=21  4*7=28  5*7=35  6*7=42  7*7=49
    1*8=8   2*8=16  3*8=24  4*8=32  5*8=40  6*8=48  7*8=56  8*8=64
    1*9=9   2*9=18  3*9=27  4*9=36  5*9=45  6*9=54  7*9=63  8*9=72  9*9=81
    

    倒序打印

    package main
    
    import "fmt"
    
    func main() {
    	for i := 1; i < 10; i++ {
    		for j := i; j < 10; j++ {
    			fmt.Printf("%d*%d=%d	", i, j, i*j)
    		}
    		fmt.Println()
    	}
    }
    >>>
    1*1=1   1*2=2   1*3=3   1*4=4   1*5=5   1*6=6   1*7=7   1*8=8   1*9=9
    2*2=4   2*3=6   2*4=8   2*5=10  2*6=12  2*7=14  2*8=16  2*9=18
    3*3=9   3*4=12  3*5=15  3*6=18  3*7=21  3*8=24  3*9=27
    4*4=16  4*5=20  4*6=24  4*7=28  4*8=32  4*9=36
    5*5=25  5*6=30  5*7=35  5*8=40  5*9=45
    6*6=36  6*7=42  6*8=48  6*9=54
    7*7=49  7*8=56  7*9=63
    8*8=64  8*9=72
    9*9=81
    

    编写代码打印出200-1000之间的质数(素数)

    package main
    
    import "fmt"
    
    func main() {
    
    	for i := 200; i < 1000; i++ {
    		flag := true
    		//判断i是否为质数,是打印,反之不打印
    		for j := 2; j < i; j++ {
    			if i%j == 0 {
    				//不是质数
    				flag = false
    				break
    			}
    		}
    		if flag {
    			fmt.Printf("%d是质数
    ", i)
    		}
    	}
    }
    >>>
    211是质数
    223是质数
    227是质数
    229是质数
    233是质数
    239是质数
    241是质数
    251是质数
    257是质数
    263是质数
    269是质数
    271是质数
    277是质数
    281是质数
    283是质数
    293是质数
    307是质数
    311是质数
    313是质数
    317是质数
    331是质数
    337是质数
    347是质数
    349是质数
    353是质数
    359是质数
    367是质数
    373是质数
    379是质数
    383是质数
    389是质数
    397是质数
    401是质数
    409是质数
    419是质数
    421是质数
    431是质数
    433是质数
    439是质数
    443是质数
    449是质数
    457是质数
    461是质数
    463是质数
    467是质数
    479是质数
    487是质数
    491是质数
    499是质数
    503是质数
    509是质数
    521是质数
    523是质数
    541是质数
    547是质数
    557是质数
    563是质数
    569是质数
    571是质数
    577是质数
    587是质数
    593是质数
    599是质数
    601是质数
    607是质数
    613是质数
    617是质数
    619是质数
    631是质数
    641是质数
    643是质数
    647是质数
    653是质数
    659是质数
    661是质数
    673是质数
    677是质数
    683是质数
    691是质数
    701是质数
    709是质数
    719是质数
    727是质数
    733是质数
    739是质数
    743是质数
    751是质数
    757是质数
    761是质数
    769是质数
    773是质数
    787是质数
    797是质数
    809是质数
    811是质数
    821是质数
    823是质数
    827是质数
    829是质数
    839是质数
    853是质数
    857是质数
    859是质数
    863是质数
    877是质数
    881是质数
    883是质数
    887是质数
    907是质数
    911是质数
    919是质数
    929是质数
    937是质数
    941是质数
    947是质数
    953是质数
    967是质数
    971是质数
    977是质数
    983是质数
    991是质数
    997是质数
    
  • 相关阅读:
    codeforces 552 C Vanya and Scales
    CGlib小记
    关于camera senor的power引脚问题
    Android实战简易教程-第四十五枪(SlideSwitch-好看又有用的开关button)
    iOS UITableViewCell 几个方法的优先级
    android.app.Fragment与android.support.v4.app.Fragment不一致

    Delphi ADOQuery连接数据库的查询、插入、删除、修改
    updatebatch
    类方法调用
  • 原文地址:https://www.cnblogs.com/remixnameless/p/13121518.html
Copyright © 2020-2023  润新知