语法:
if 布尔表达式 {
/* 在布尔表达式为 true 时执行 */
} else {
/* 在布尔表达式为 false 时执行 */
}
与C的if … else语句的区别是条件不用加括号
实例
package main
import "fmt"
func main() {
/* 局部变量定义 */
var a int = 100;
/* 判断布尔表达式 */
if a < 20 {
/* 如果条件为 true 则执行以下语句 */
fmt.Printf("a 小于 20\n" );
} else {
/* 如果条件为 false 则执行以下语句 */
fmt.Printf("a 不小于 20\n" );
}
fmt.Printf("a 的值为 : %d\n", a);
}
语法:
switch var1 {
case val1:
...
case val2:
...
default:
...
}
break
。fallthrough
实例:
package Switch
import "fmt"
func Switch() {
grade := 'B'
marks := 90
switch marks {
case 90:
grade = 'A'
case 80:
grade = 'B'
case 70, 60, 50:
grade = 'C'
default:
grade = 'D'
}
switch {
case grade == 'A':
fmt.Println("优秀")
case grade == 'B':
fmt.Println("良好")
case grade == 'C':
fmt.Println("及格")
default:
fmt.Println("不及格")
}
fmt.Println("你的等级是:", grade)
}
type-switch
来判断某个 interface
变量中实际存储的变量类型。Type Switch 语法格式如下
switch x.(type){
case type:
statement(s);
case type:
statement(s);
/* 你可以定义任意个数的case */
default: /* 可选 */
statement(s);
}
实例:
package Switch
import "fmt"
func TypeSwitch() {
var x interface{}
switch i := x.(type) {
case nil:
fmt.Printf("x的类型: %T\n", i)
case int:
fmt.Println("x是int型")
case float64:
fmt.Println("x是float64型")
case func(int) float64:
fmt.Println("x是func(int)型")
case bool, string:
fmt.Println("x是bool或string型")
default:
fmt.Println("未知型")
}
}
fallthrough
fallthrough
会强制执行后面的 case 语句,包括default
,fallthrough
不会判断下一条case的表达式结果是否为 true。fallthrough
只会强制执行后面一条case语句,而不是后面的全部;实例1:
package Switch
import "fmt"
func Fallthrough() {
switch {
case false:
fmt.Println("1.case条件语句为false")
fallthrough
case true:
fmt.Println("2.case条件语句为true")
fallthrough
case false:
fmt.Println("3.case条件语句为false")
fallthrough
case true:
fmt.Println("4.case条件语句为true")
fallthrough
case false:
fmt.Println("5.case条件语句为false")
fallthrough
default:
fmt.Println("6.默认case")
}
}
实例2:
package Switch
import "fmt"
func Fallthrough() {
switch {
case false:
fmt.Println("1.case条件语句为false")
fallthrough
case true:
fmt.Println("2.case条件语句为true")
fallthrough
case false:
fmt.Println("3.case条件语句为false")
//fallthrough
case true:
fmt.Println("4.case条件语句为true")
//fallthrough
case false:
fmt.Println("5.case条件语句为false")
//fallthrough
default:
fmt.Println("6.默认case")
}
}
select 是 Go 中的一个控制结构,类似于 switch 语句。
Go 编程语言中 select 语句的语法如下:
select {
case <- channel1:
// 执行的代码
case value := <- channel2:
// 执行的代码
case channel3 <- value:
// 执行的代码
// 你可以定义任意数量的 case
default:
// 所有通道都没有准备好,执行的代码
}
实例1:
package Select
import (
"fmt"
"time"
)
func Select() {
c1 := make(chan string)
c2 := make(chan string)
go func() {
time.Sleep(1 * time.Second)
c1 <- "one"
}()
go func() {
time.Sleep(2 * time.Second)
c2 <- "two"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
fmt.Println("received", msg1)
case msg2 := <-c2:
fmt.Println("received", msg2)
}
}
}
实例2:
package Select
import (
"fmt"
"time"
)
func Select1() {
c1 := make(chan string)
c2 := make(chan string)
go func() {
time.Sleep(1 * time.Second)
c1 <- "one"
}()
go func() {
time.Sleep(2 * time.Second)
c2 <- "two"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
fmt.Println("received", msg1)
case msg2 := <-c2:
fmt.Println("received", msg2)
}
}
}
func Select2() {
// 定义两个通道
ch1 := make(chan string)
ch2 := make(chan string)
// 启动两个 goroutine,分别从两个通道中获取数据
go func() {
for {
ch1 <- "from 1"
}
}()
go func() {
for {
ch2 <- "from 2"
}
}()
// 使用 select 语句非阻塞地从两个通道中获取数据
for {
select {
case msg1 := <-ch1:
fmt.Println(msg1)
case msg2 := <-ch2:
fmt.Println(msg2)
default:
// 如果两个通道都没有可用的数据,则执行这里的语句
fmt.Println("no message received")
}
}
}
for 循环是一个循环控制结构,可以执行指定次数的循环。
Go 语言的 For 循环有 3 种形式,只有其中的一种使用分号。
for
一样:for init; condition; post { }
init: 一般为赋值表达式,给控制变量赋初值;
condition: 关系表达式或逻辑表达式,循环控制条件;
post: 一般为赋值表达式,给控制变量增量或减量。
while
一样:for condition { }
for(;;)
一样:for { }
for key, value := range oldMap {
newMap[key] = value
}
以上代码中的 key 和 value 是可以省略。
如果只想读取 key,格式如下:
for key := range oldMap
或者这样:
for key, _ := range oldMap
如果只想读取 value,格式如下:
for _, value := range oldMap
实例1:
package For
import "fmt"
func For() {
sum := 0
for i := 1; i <= 10; i++ {
sum += i
}
fmt.Println(sum)
}
实例2:
package For
import "fmt"
func While() {
sum := 1
for sum <= 10 {
sum += sum
}
fmt.Println(sum)
}
实例3:
package For
import "fmt"
func main() {
sum := 0
for {
sum++ // 无限循环下去
}
fmt.Println(sum) // 无法输出
}
实例4:
package For
import "fmt"
func Range() {
strings := []string{"google", "runoob"}
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)
}
}
实例5:
package For
import "fmt"
func Range() {
map1 := make(map[int]float32)
map1[1] = 1.0
map1[2] = 2.0
map1[3] = 3.0
map1[4] = 4.0
// 读取 key 和 value
for key, value := range map1 {
fmt.Printf("key is: %d - value is: %f\n", key, value)
}
// 读取 key
for key := range map1 {
fmt.Printf("key is: %d\n", key)
}
// 读取 value
for _, value := range map1 {
fmt.Printf("value is: %f\n", value)
}
}
defer语句被用于预定对一个函数的调用。可以把这类被defer语句调用的函数称为延迟函数。
defer语句会将其后的函数调用推迟到当前所在函数体的生命周期结束后再执行,类似于c++的析构函数。这个特性常用于处理成对的操作,如打开/关闭文件、获取/释放锁、连接/断开连接等,确保资源被适当地释放,即使在发生错误或提前返回的情况下也能保证执行。
defer作用:
如果一个函数中有多个defer语句,它们会以LIFO(后进先出)的顺序执行。
实例
package Defer
import "fmt"
func Defer() {
defer fmt.Println("main end1")
defer fmt.Println("main end2")
fmt.Println("0")
fmt.Println("1")
}
package Defer
import "fmt"
func deferFunc() int {
fmt.Println("defer func called...")
return 0
}
func returnFunc() int {
fmt.Println("return func caller...")
return 0
}
func ReturnAndDefer() int {
defer deferFunc()
return returnFunc()
}
}
之前的,因此return会先执行,defer再执行;运行时panic异常一旦被引发就会导致程序崩溃。
recover
。它可以是当前的程序从运行时panic的状态中恢复并重新获得流程控制权。实例1:
package main
import "fmt"
func recoverFunc(i int) {
//定义10个元素的数组
var arr [10]int
//错误拦截要在产生错误前设置
//这里使用匿名函数进行错误拦截,在进行defer调用
//相当于这个匿名函数在recoverFunc的生命周期结束后才被调用
defer func() {
//设置recover拦截错误信息
err := recover()
//产生panic异常,打印错误信息
if err != nil {
fmt.Println(err)
}
}()
//根据函数参数为数组元素赋值
//如果i的值超过数组下标 会报错误:数组下标越界
arr[i] = 2
}
func main() {
recoverFunc(10)
fmt.Println("程序继续执行...")
}
recoverFunc
的生命周期结束后进行调用,recoverFunc
函数中出现了数组越界的错误,之后被recover()
拦截了,程序得以继续执行;实例2:
package main
import "fmt"
func handlePanic() {
if r := recover(); r != nil {
fmt.Println("Recovered:", r)
}
}
func performTask() {
defer handlePanic()
fmt.Println("Performing some task...")
panic("Oops! Something went wrong!")
fmt.Println("Task completed.")
}
func main() {
performTask()
fmt.Println("Main function continues.")
}
performTask
函数执行结束,defer调用的函数开始出栈,执行handlePanic
函数,panic异常引发后,在handlePanic
函数中recover拦截了异常,打印出错误信息,并让main
函数继续运行。