条件控制

寒江蓑笠翁大约 6 分钟

条件控制

在Go中,条件控制语句总共有三种ifswitchselectselect相对前两者而言比较特殊,本节不会讲解,将会留到并发那一节再做介绍。


if else

if else 至多两个判断分支,语句格式如下

if expression {

}

或者

if expression {

}else {

}

expression必须是一个布尔表达式,即结果要么为真要么为假,必须是一个布尔值,例子如下:

func main() {
   a, b := 1, 2
   if a > b {
      b++
   } else {
      a++
   }
}

也可以把表达式写的更复杂些,必要时为了提高可读性,应当使用括号来显式的表示谁应该优先计算。

func main() {
   a, b := 1, 2
    if a<<1%100+3 > b*100/20+6 { // (a<<1%100)+3 > (b*100/20)+6
      b++
   } else {
      a++
   }
}

同时if语句也可以包含一些简单的语句,例如:

func main() {
	if x := 1 + 1; x > 2 {
		fmt.Println(x)
	}
}

else if

else if 语句可以在if else的基础上创建更多的判断分支,语句格式如下:

if expression1 {

}else if expression2 {

}else if expression3 {

}else {

}

在执行的过程中每一个表达式的判断是从左到右,整个if语句的判断是从上到下 。一个根据成绩打分的例子如下,第一种写法

func main() {
   score := 90
   var ans string
   if score == 100 {
      ans = "S"
   } else if score >= 90 && score < 100 {
      ans = "A"
   } else if score >= 80 && score < 90 {
      ans = "B"
   } else if score >= 70 && score < 80 {
      ans = "C"
   } else if score >= 60 && score < 70 {
      ans = "E"
   } else if score >= 0 && score < 60 {
      ans = "F"
   } else {
      ans = "nil"
   }
   fmt.Println(ans)
}

第二种写法利用了if语句是从上到下的判断的前提,所以代码要更简洁些。

func main() {
	score := 90
	var ans string
	if score >= 0 && score < 60 {
		ans = "F"
	} else if score < 70 {
		ans = "D"
	} else if score < 80 {
		ans = "C"
	} else if score < 90 {
		ans = "B"
	} else if score < 100 {
		ans = "A"
	} else if score == 100 {
		ans = "S"
    }else {
        ans = "nil"
    }
	fmt.Println(ans)
}

switch

switch语句也是一种多分支的判断语句,语句格式如下:

switch expr {
	case case1:
		statement1
	case case2:
		statement2
	default:
		default statement
}

一个简单的例子如下

func main() {
   str := "a"
   switch str {
   case "a":
      str += "a"
      str += "c"
   case "b":
      str += "bb"
      str += "aaaa"
   default: // 当所有case都不匹配后,就会执行default分支
      str += "CCCC"
   }
   fmt.Println(str)
}

还可以在表达式之前编写一些简单语句,例如声明新变量

func main() {
	switch num := f(); { // 等价于 switch num := f(); true {
	case num >= 0 && num <= 1:
		num++
	case num > 1:
		num--
		fallthrough
	case num < 0:
		num += num
	}
}

func f() int {
	return 1
}

switch语句也可以没有入口处的表达式。

func main() {
   num := 2
   switch { // 等价于 switch true { 
   case num >= 0 && num <= 1:
      num++
   case num > 1:
      num--
   case num < 0:
      num *= num
   }
   fmt.Println(num)
}

通过fallthrough关键字来继续执行相邻的下一个分支。

func main() {
   num := 2
   switch {
   case num >= 0 && num <= 1:
      num++
   case num > 1:
      num--
      fallthrough // 执行完该分支后,会继续执行下一个分支
   case num < 0:
      num += num
   }
   fmt.Println(num)
}

label

标签语句,给一个代码块打上标签,可以是gotobreakcontinue的目标。例子如下:

func main() {
	A: 
		a := 1
	B:
		b := 2
}

单纯的使用标签是没有任何意义的,需要结合其他关键字来进行使用。


goto

goto将控制权传递给在同一函数对应标签的语句,示例如下:

func main() {
   a := 1
   if a == 1 {
      goto A
   } else {
      fmt.Println("b")
   }
A:
   fmt.Println("a")
}

在实际应用中goto用的很少,跳来跳去的很降低代码可读性,性能消耗也是一个问题。