6.1 if语句
go语言的常用控制流程有if和for,没有while, 而switch和goto是为了简化代码,降低重复代码,属于扩展的流程控制。
if语句的结构:
if 布尔表达式 {/* 在布尔表达式为 true 时执行 */}if 布尔表达式 {/* 在布尔表达式为 true 时执行 */} else {/* 在布尔表达式为 false 时执行 */}if 布尔表达式1 {/* 在布尔表达式1为 true 时执行 */} else if 布尔表达式2{/* 在布尔表达式1为 false ,布尔表达式2为true时执行 */} else{/* 在上面两个布尔表达式都为false时,执行*/}
package mainimport "fmt"func main() {/* 定义局部变量 */var a int = 10/* 使用 if 语句判断布尔表达式 */if a < 20 {/* 如果条件为 true 则执行以下语句 */fmt.Printf("a 小于 20\n" )}fmt.Printf("a 的值为 : %d\n", a)}
if还有一个变体也很常用
package mainimport ("fmt")func main() {if num := 10; num % 2 == 0 { //checks if number is evenfmt.Println(num,"is even")} else {fmt.Println(num,"is odd")}}
if err := Connect(); err != nil {}
这种写法可 以将返回值与判断放在一行进行处理,而且返回值的作用范围被限制在if、 else 语句组合中。
提示:
在编程中,变量在其实现了变量的功能后 ,作用范围越小 ,所造成的问题可能性越小,每一个变量代表一个状态,有状态的地方,状态就会被修改,函数的局部变量只会影响一个函数的执行, 但全局 变量可能会影响所有代码的执行状态,因此限制变量的作用范围对代码的稳定性有很大的帮助 。
package mainimport ("errors""fmt")func test() error {return errors.New("error")}func main() {if err := test(); err != nil {fmt.Println("error happen")}fmt.Println(err) //此处会报错}
6.2 for循环
- Go 语言的 For 循环有 3 种形式,只有其中的一种使用分号。
//和 C 语言的 for 一样:for init; condition; post { }//和 C 的 while 一样:for condition { }//和 C 的 for(;;) 一样:for { }
- init: 一般为赋值表达式,给控制变量赋初值;
- condition: 关系表达式或逻辑表达式,循环控制条件;
- post: 一般为赋值表达式,给控制变量增量或减量。
for语句执行过程如下:
- 1、先对表达式 1 赋初值;
- 2、判别赋值表达式 init 是否满足给定条件,若其值为真,满足循环条件,则执行循环体内语句,然后执行 post,进入第二次循环,再判别 condition;否则判断 condition 的值为假,不满足条件,就终止for循环,执行循环体外语句。

- for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。格式如下:
```go package main import “fmt”for key, value := range oldMap {newMap[key] = value}
func main() { strings := []string{“bobby”, “imooc”} for i, s := range strings { fmt.Println(i, s) }
numbers := [6]int{1, 2, 3, 5}for i,x:= range numbers {fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)}
}
<a name="AHxEm"></a># 6.3 goto语句Go语言的goto语句可以无条件转移到过程中指定的行。<br />goto语句通常与条件语句配合使用,可用来实现条件转移,构成循环,跳出循环体等功能。<br />但是,在结构化程序设计中一般不主张使用goto语句,以免造成程序流程的混乱,使理解和调试程序都产生困难。<br />goto语法格式如下:```powershellgoto label;...label:statement;

package mainimport "fmt"func main() {/* 定义局部遍历 */var a int = 10/* 循环 */LOOP:for a < 20 {if a == 15 {/* 跳过迭代 */a = a + 1goto LOOP}fmt.Printf("a的值为:%d\n", a)a++}}
应用场景
使用goto退出多层循环
package mainimport "fmt"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")}
//优化后package mainimport "fmt"func main() {for x := 0; x < 10; x++ {for y := 0; y < 10; y++ {if y == 2 {//跳转到标签goto breakHere}}}//手动返回, 避免执行进入标签return//标签breakHere:fmt.Println("done")}
使用goto集中处理错误
多处错误处理存在代码重复时是非常棘手的,例如:
err := firstCheckError()if err != nil {fmt.Println(err)exitProcess()return}err = secondCheckError()if err != nil {fmt.Println(err)exitProcess()return}fmt.Println("done")
上述代码修改一下
err := firstCheckError()if err != nil {goto onExit}err = secondCheckError()if err != nil {goto onExit}fmt.Println("done")returnonExit:fmt.Println(err)exitProcess()
6.4 switch语句
- switch 语句用于基于不同条件执行不同动作,每一个 case 分支都是唯一的,从上至下逐一测试,直到匹配为止。
```go package mainswitch var1 {case val1:...case val2:...default:...
import “fmt”
func main() { / 定义局部变量 / var grade string = “B” var marks int = 90
switch marks {
case 90: grade = “A”
case 80: grade = “B”
case 50,60,70 : grade = “C”
default: grade = “D”
}
switch {
case grade == “A” :
fmt.Printf(“优秀!\n” )
case grade == “B”, grade == “C” :
fmt.Printf(“良好\n” )
case grade == “D” :
fmt.Printf(“及格\n” )
case grade == “F”:
fmt.Printf(“不及格\n” )
default:
fmt.Printf(“差\n” );
}
fmt.Printf(“你的等级是 %s\n”, grade );
}
<a name="de7sV"></a>## Type Switchswitch 语句还可以被用于 type-switch 来判断某个 interface 变量中实际存储的变量类型。<br />Type Switch 语法格式如下:```goswitch x.(type){case type:statement(s);case type:statement(s);/* 你可以定义任意个数的case */default: /* 可选 */statement(s);}
package mainimport "fmt"func main() {var x interface{}switch i := x.(type) {case nil:fmt.Printf(" x 的类型 :%T",i)case int:fmt.Printf("x 是 int 型")case float64:fmt.Printf("x 是 float64 型")case func(int) float64:fmt.Printf("x 是 func(int) 型")case bool, string:fmt.Printf("x 是 bool 或 string 型" )default:fmt.Printf("未知型")}}
一分支多值
不同的 case 表达式使用逗号分隔。
var a = "mum"switch a {case "mum", "daddy":fmt.Println("family")}
分支表达式
var r int = 11switch {case r > 10 && r < 20:fmt.Println(r)}
6.5 python中为什么没有switch
查看Python官方:PEP 3103-A Switch/Case Statement
发现其实实现Switch Case需要被判断的变量是可哈希的和可比较的,这与Python倡导的灵活性有冲突。在实现上,优化不好做,可能到最后最差的情况汇编出来跟If Else组是一样的。所以Python没有支持。
https://www.python.org/dev/peps/pep-3103/score = 90switch = {90: lambda : print("A"),80: lambda : print("B"),70: lambda : print("C"),}switch[score]()
class switch(object):def __init__(self, value):self.value = valueself.fall = Falsedef __iter__(self):"""Return the match method once, then stop"""yield self.matchraise StopIterationdef match(self, *args):"""Indicate whether or not to enter a case suite"""if self.fall or not args:return Trueelif self.value in args: # changed for v1.5, see belowself.fall = Truereturn Trueelse:return False# The following example is pretty much the exact use-case of a dictionary,# but is included for its simplicity. Note that you can include statements# in each suite.v = 'ten'for case in switch(v):if case('one'):print 1breakif case('two'):print 2breakif case('ten'):print 10breakif case('eleven'):print 11breakif case(): # default, could also just omit condition or 'if True'print "something else!"# No need to break here, it'll stop anyway# break is used here to look as much like the real thing as possible, but# elif is generally just as good and more concise.# Empty suites are considered syntax errors, so intentional fall-throughs# should contain 'pass'c = 'z'for case in switch(c):if case('a'): pass # only necessary if the rest of the suite is emptyif case('b'): pass# ...if case('y'): passif case('z'):print "c is lowercase!"breakif case('A'): pass# ...if case('Z'):print "c is uppercase!"breakif case(): # defaultprint "I dunno what c was!"# As suggested by Pierre Quentel, you can even expand upon the# functionality of the classic 'case' statement by matching multiple# cases in a single shot. This greatly benefits operations such as the# uppercase/lowercase example above:import stringc = 'A'for case in switch(c):if case(*string.lowercase): # note the * for unpacking as argumentsprint "c is lowercase!"breakif case(*string.uppercase):print "c is uppercase!"breakif case('!', '?', '.'): # normal argument passing style also appliesprint "c is a sentence terminator!"breakif case(): # defaultprint "I dunno what c was!"# Since Pierre's suggestion is backward-compatible with the original recipe,# I have made the necessary modification to allow for the above usage.
