您好,登錄后才能下訂單哦!
這篇文章主要講解了“Golang中的流程控制有哪些及怎么實現”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Golang中的流程控制有哪些及怎么實現”吧!
Go語言基礎之流程控制主要包括以下內容:
條件語句if
條件語句switch
條件語句select
循環語句for
循環語句range
循環控制Goto、Break、Continue
Go語言中if
條件判斷的格式如下:
if 表達式1 {
分支1
} else if 表達式2 {
分支2
} else{
分支3
}
前端的同學想必對js相對熟悉,相對于js來說,go表達式去掉了括號()
,但同時給了一些約束,與if
匹配的左括號{
必須與if和表達式
放在同一行,{
放在其他位置會觸發編譯錯誤。 同理,與else
匹配的{
也必須與else
寫在同一行,else
也必須與上一個if
或else if
右邊的大括號在同一行。
x := 0
// if x > 10 // Error: missing condition in if statement
// {
// }
if n := "abc"; x > 0 { // 初始化語句未必就是定義變量, 如 println("init") 也是可以的。
println(n[2])
} else if x < 0 { // 注意 else if 和 else 左大括號位置。
println(n[1])
} else {
println(n[0])
}
*不支持三元操作符(三目運算符) "a > b ? a : b"。
package main
import "fmt"
func main() {
/* 定義局部變量 */
var a int = 10
/* 使用 if 語句判斷布爾表達式 */
if a < 20 {
/* 如果條件為 true 則執行以下語句 */
fmt.Printf("a 小于 20\n" )
}
fmt.Printf("a 的值為 : %d\n", a)
}
以上代碼執行結果為:
a 小于 20
a 的值為 : 10
switch 語句用于基于不同條件執行不同動作,每一個 case 分支都是唯一的,從上直下逐一測試,直到匹配為止。 Golang switch 分支表達式可以是任意類型,不限于常量。可省略 break,默認自動終止。
package main
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
select 語句類似于 switch 語句,但是select會隨機執行一個可運行的case。如果沒有case可運行,它將阻塞,直到有case可運行。
select 是Go中的一個控制結構,類似于用于通信的switch語句。每個case必須是一個通信操作,要么是發送要么是接收。 select 隨機執行一個可運行的case。如果沒有case可運行,它將阻塞,直到有case可運行。一個默認的子句應該總是可運行的。
以下描述了 select 語句的語法:
select可以監聽channel的數據流動 每個case都必須是一個通信
所有channel表達式都會被求值
所有被發送的表達式都會被求值
如果任意某個通信可以進行,它就執行;其他被忽略。
如果有多個case都可以運行,Select會隨機公平地選出一個執行。其他不會執行。
否則:
如果有default子句,則執行該語句。
如果沒有default字句,select將阻塞,直到某個通信可以運行;Go不會重新對channel或值進行求值。
package main
import "fmt"
func main() {
var c1, c2, c3 chan int
var i1, i2 int
select {
case i1 = <-c1:
fmt.Printf("received ", i1, " from c1\n")
case c2 <- i2:
fmt.Printf("sent ", i2, " to c2\n")
case i3, ok := (<-c3): // same as: i3, ok := <-c3
if ok {
fmt.Printf("received ", i3, " from c3\n")
} else {
fmt.Printf("c3 is closed\n")
}
default:
fmt.Printf("no communication\n")
}
}
以上代碼執行結果為:
no communication
select的用法與switch語法非常類似,由select開始的一個新的選擇塊,每個選擇條件由case語句來描述
與switch語句可以選擇任何使用相等比較的條件相比,select有比較多的限制,其中最大的一條限制就是每個case語句里必須是一個IO操作
在一個select語句中,Go會按順序從頭到尾評估每一個發送和接收的語句。 select { //不停的在這里檢測
case <-chanl : //檢測有沒有數據可以讀
//如果chanl成功讀取到數據,則進行該case處理語句
case chan2 <- 1 : //檢測有沒有可以寫
//如果成功向chan2寫入數據,則進行該case處理語句
//假如沒有default,那么在以上兩個條件都不成立的情況下,就會在此阻塞//一般default會不寫在里面,select中的default子句總是可運行的,因為會很消耗CPU資源
default:
//如果以上都沒有符合條件,那么則進行default處理流程
}
如果其中的任意一個語句可以繼續執行(即沒有被阻塞),那么就從那些可以執行的語句中任意選擇一條來使用。 如果沒有任意一條語句可以執行(即所有的通道都被阻塞),那么有兩種可能的情況: ①如果給出了default語句,那么就會執行default的流程,同時程序的執行會從select語句后的語句中恢復。 ②如果沒有default語句,那么select語句將被阻塞,直到至少有一個case可以進行下去。
//比如在下面的場景中,使用全局resChan來接受response,如果時間超過3S,resChan中還沒有數據返回,則第二條case將執行
var resChan = make(chan int)
// do request
func test() {
select {
case data := <-resChan:
doData(data)
case <-time.After(time.Second * 3):
fmt.Println("request time out")
}
}
func doData(data int) {
//...
}
和if一樣,相對于js,go語言的for循環也去掉了括號(),其他并沒有太大的區別。
package main
import "fmt"
func main() {
var b int = 15
var a int
numbers := [6]int{1, 2, 3, 5}
/* for 循環 */
for a := 0; a < 10; a++ {
fmt.Printf("a 的值為: %d\n", a)
}
for a < b {
a++
fmt.Printf("a 的值為: %d\n", a)
}
for i,x:= range numbers {
fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)
}
}
以上實例運行輸出結果為:
a 的值為: 0
a 的值為: 1
a 的值為: 2
a 的值為: 3
a 的值為: 4
a 的值為: 5
a 的值為: 6
a 的值為: 7
a 的值為: 8
a 的值為: 9
a 的值為: 1
a 的值為: 2
a 的值為: 3
a 的值為: 4
a 的值為: 5
a 的值為: 6
a 的值為: 7
a 的值為: 8
a 的值為: 9
a 的值為: 10
a 的值為: 11
a 的值為: 12
a 的值為: 13
a 的值為: 14
a 的值為: 15
第 0 位 x 的值 = 1
第 1 位 x 的值 = 2
第 2 位 x 的值 = 3
第 3 位 x 的值 = 5
第 4 位 x 的值 = 0
第 5 位 x 的值 = 0
Golang range類似迭代器操作,返回 (索引, 值) 或 (鍵, 值)。
for 循環的 range 格式可以對 slice、map、數組、字符串等進行迭代循環。格式如下:
登錄后復制 for 和 for range有什么區別?for key, value := range oldMap {
newMap[key] = value
}
package main
func main() {
s := "abc"
// 忽略 2nd value,支持 string/array/slice/map。
for i := range s {
println(s[i])
}
// 忽略 index。
for _, c := range s {
println(c)
}
// 忽略全部返回值,僅迭代。
for range s {
}
m := map[string]int{"a": 1, "b": 2}
// 返回 (key, value)。
for k, v := range m {
println(k, v)
}
}
輸出結果:
97
98
99
97
98
99
a 1
b 2
主要是使用場景不同
for可以遍歷array和slice,遍歷key為整型遞增的map,遍歷string
for range可以完成所有for可以做的事情,卻能做到for不能做的,包括遍歷key為string類型的map并同時獲取key和value,遍歷channel
循環控制語句
循環控制語句可以控制循環體內語句的執行過程。
GO 語言支持以下幾種循環控制語句:
1.三個語句都可以配合標簽(label)使用
2.標簽名區分大小寫,定以后若不使用會造成編譯錯誤
3.continue、break配合標簽(label)可用于多層循環跳出
4.goto是調整執行位置,與continue、break配合標簽(label)的結果并不相同
break(跳出循環)
:
continue(繼續下次循環)break
語句可以結束for
、switch
和select
的代碼塊。break
語句還可以在語句后面添加標簽,表示退出某個標簽對應的代碼塊,標簽要求必須定義在對應的for
、switch
和 select
的代碼塊上。
continue(繼續下次循環)
:continue
語句可以結束當前循環,開始下一次的循環迭代過程,僅限在for
循環內使用。在 continue
語句后添加標簽時,表示開始標簽對應的循環
goto
語句通過標簽
進行代碼間的無條件跳轉。goto
語句可以在快速跳出循環、避免重復退出上有一定的幫助。Go語言中使用goto
語句能簡化一些代碼的實現過程。 例如雙層嵌套的for循環要退出時:
使用func gotoDemo1() {
var breakFlag bool
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j == 2 {
// 設置退出標簽
breakFlag = true
break
}
fmt.Printf("%v-%v\n", i, j)
}
// 外層for循環判斷
if breakFlag {
break
}
}
}
goto
語句能簡化代碼:func gotoDemo2() {
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j == 2 {
// 設置退出標簽
goto breakTag
}
fmt.Printf("%v-%v\n", i, j)
}
}
return
// 標簽
breakTag:
fmt.Println("結束for循環")
}
感謝各位的閱讀,以上就是“Golang中的流程控制有哪些及怎么實現”的內容了,經過本文的學習后,相信大家對Golang中的流程控制有哪些及怎么實現這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。