语法:
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: ... }
实例:
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 语法格式如下
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 会强制执行后面的 case 语句,包括default,fallthrough 不会判断下一条case的表达式结果是否为 true。
实例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) } } }
select 语句等待两个通道的数据。如果接收到 c1 的数据,就会打印 “received one”;如果接收到 c2 的数据,就会打印 “received two”。
实例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") } } }
以上实例执行后会不断地从两个通道中获取到的数据,当两个通道都没有可用的数据时,会输出 “no message received”。
for 循环是一个循环控制结构,可以执行指定次数的循环。
Go 语言的 For 循环有 3 种形式,只有其中的一种使用分号。
for init; condition; post { }
init: 一般为赋值表达式,给控制变量赋初值;
condition: 关系表达式或逻辑表达式,循环控制条件;
post: 一般为赋值表达式,给控制变量增量或减量。
for condition { }
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() }
运行时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("程序继续执行...") }
实例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.") }