Go語言的流程控制主要分為三大類:
1. 條件判斷 2. 循環控制 3. 無條件跳轉
Go語言的條件判斷由if ... else if ... else 語句實現,條件表達式值必須是布爾類型,可省略圓括號,但是花括號不能省略且左花括號不能另起一行,比如:
if 7%2 == 0 {
fmt.Println("7 is even")
} else {
fmt.Println("7 is odd")
}
if 8%4 == 0 { //可以沒有else只有if語句
fmt.Println("8 is divisible by 4")
}Go語言比較特別的是在條件判讀語句中支持初始化語句,允許定義局部變量,但是這個變量的作用域僅限于該條件邏輯塊內,比如:
if num := 9; num < 0 {
fmt.Println(num, "is negative")
} else if num < 10 {
fmt.Println(num, "has 1 digit")
} else {
fmt.Println(num, "has multiple digits")
}最典型的應用就是字典的查找:
if v, ok := map1[key1]; ok{
...
}優化建議:
對于那些過于復雜的組合條件判斷,建議獨立出來封裝成函數,將流程控制和實現細節分離,使你的代碼更加模塊化,提高可讀性.
有些時需要寫很多的if-else實現一些復雜的邏輯處理,這時代碼看上去就很羅嗦很冗長,而且也不易于以后的維護,用switch...case來很好的解決這個問題.
switch...case
switch與if類似,也用于選擇執行,執行的過程從上至下順序匹配各個case,基本用法如下:
switch sExpr {
case expr1:
some instructions
case expr2:
some other instructions
case expr3:
some other instructions
default:
other code
}switch中的表達式可以不是常量或字符串,甚至可以沒有表達式,若沒有表達式則匹配true, 如同if-else if-else,與 其它編程語言的switch用法基本相同,不同的是在每個case中隱藏了break,不過也可以顯示加入break。 當case匹配成功后,處理當前case的處理邏輯,正常情況下,處理完成后就跳出整個switch,但這不是絕對的, 可以使用fallthrough強迫程序執行后面的case; 如果沒有任何case匹配成功,則執行default邏輯,比如:
免寫break:
{
i := 2
switch i { //將i 與case條件匹配
case 1:
fmt.Println("one") //break沒有實際意義,直接跳出switch
case 2:
fmt.Println("two")
case 3:
fmt.Println("three")
}
}多表達式判斷:
{
switch time.Now().Weekday() {
case time.Saturday, time.Sunday: //在同一個case中可以寫多個表達式,它們之間是邏輯或的關系
fmt.Println("it's the weekend")
default:
fmt.Println("it's a weekday")
}
}無表達式:
{
t := time.Now()
switch { //沒有表達式,相當于if-else
case t.Hour() < 12:
fmt.Println("it's before noon")
default:
fmt.Println("it's after noon")
}
}fallthrough:
{
i := 2
switch i {
case 1:
fmt.Println("one")
case 2:
fmt.Println("two")
fallthrough //使用fallthrough強迫程序執行后面的case
case 3:
fmt.Println("three")
}
}for是Go語言中僅有的一種循環語句,下面是常見的三種用法:
for j := 7; j <= 9; j++ { //典型的用法 initial/condition/after
fmt.Println(j)
}
i := 1
for i <= 3 { //類似while(i <= 3){} 或for ; i<=3 ;;{}
fmt.Println(i)
i = i + 1
}
for { //類似while(true){} 或for true {}
fmt.Println("loop")
...
break
}PS:初始化語句只會被執行一次,并且初始化表達式支持函數調用或定義局部變量
在日常開發中for經常與range搭配,for...range被用來遍歷字符串、數組、切片、字典和通道等,返回索引和鍵值數據,比如:
{ for i, c := range "go" { //range string
fmt.Println(i, c)
}
nums := []int{2, 3, 4}
for i, num := range nums { //range array/slice
fmt.Println(i, ":", num)
}
kvs := map[string]string{"a": "apple", "b": "banana"}
for k, v := range kvs { //range map
fmt.Printf("%s -> %s\n", k, v)
}
chs := make(chan int,10) //range channel
chs <- 1
chs <- 2
close(chs)
for v := range chs {
fmt.Println(v)
}
}簡單歸納如下:
| data type | first value | second value |
| string | index | s[index] |
| array/slice | index | v[index] |
| map | key | value |
| channel | element |
Go語言有三種跳轉類型,分別是 continue, break, goto
continue:僅用于for循環內部 ,終止本次循環,立即進入下一輪循環 break:用于for循環, switch,select語句,終止整個語句塊的執行 goto:定點跳轉,但不能跳轉到其他函數或內層代碼塊內
看下面的例子:
func over(){
over: //label over defined and not used
println("call over")
}
func main(){
rand.Seed(time.Now().UnixNano())
for {
loop:
x := rand.Intn(100) //獲取一個100以內的隨機數
if x % 2 == 0{
continue //終止本次循環,立即進入下一輪循環
}
if x > 50{
break //終止整個語句塊的執行
}
println(x)
}
goto over //label over not defined
goto loop //goto loop jumps into block starting}goto 的習慣用法:
{
f, err := os.Open("/tmp/dat")
if err != nil{
....
goto exit
}
...
n1, err := f.Read(b1)
if err != nil{
goto end
}
...
end:
println("clear resource and exit")
f.close()
exit:
return
}借鑒: 雨痕<GO學習筆記>
討論學習: 675020908
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。