1. 程式人生 > 實用技巧 >golang 流程控制

golang 流程控制

目錄

前言

  • 不做文字的搬運工,多做靈感性記錄
  • 這是平時學習總結的地方,用做知識庫
  • 平時看到其他文章的相關知識,也會增加到這裡
  • 隨著學習深入,會進行知識拆分和彙總,所以文章會隨時更新
  • 參考的文章過多、很雜很亂,所以參考會寫不全,見諒

流程控制

主要是三大流程控制流程控制語句

1)順序控制

2)分支控制

3)迴圈控制

1.順序控制

程式從上到下逐行地執行,中間沒有任何判斷和跳轉。

  1. 注意

    • Golang中定義變數時採用合法的前向引用。

      就是說你使用變數就需要提前宣告它

2.分支語句

1.形式

  • 單分支
  • 雙分支
  • 多分支

2.單分支控制 if

基本語法

if 條件表示式 {

	執行程式碼塊

}
條件表示式為true時,就會執行{}的程式碼,注意{}是必須有的,就算你值寫一行程式碼
// golang支援在if中直接定義一個變數
if age := 20;age > 18{
    ...
}

3.雙分支語句 if

if 條件表示式 {
	執行程式碼塊 1
}else{
    執行程式碼塊 2
}

// 注意
1.條件表示式為true時,就會執行程式碼塊1,否則就執行程式碼塊2,注意{}是必須有的
2.雙分支只會執行其中的一個分支

4.多分支控制 if

if 條件表示式 {
	執行程式碼塊1
}else if 條件表示式{
    執行程式碼塊2
}else if 條件表示式{
    執行程式碼塊3
}else{
    執行程式碼塊 n
}
// 注意
else不是必須的,但多分支只能執行一個執行入口    
    

5.巢狀分支

   在一個分支結構中又完整的嵌套了另一個完整的分支結構,裡面的分支的結構稱為內層分支,外面的分支結構稱為外層分支。巢狀分支不宜過多,建議控制在3層內。

6.switch分支控制

  1. switch語句用於基於不同條件執行不同動作,每一個case分支都是唯一的,從上到下逐一測試,直到匹配為止。
  2. 匹配項後面也不需要再加break
switch 表示式{
	case 表示式1,表示式2,...:
		語句塊1
	case 表示式3,表示式4,...:
		語句塊2
		
	default:
		語句塊3
}

// 注意
1.先執行switch的表示式得到值。然後執行case的語句,進行比較,遇到相等的,就比配到,執行對應的case的語句塊,然後退出switch,如果沒有匹配成功,就會執行default語句
2.case後的表示式可以有多個,用逗號隔開
3.switch 後面也可以不帶表示式,直接跟上(:)類似 if - case 分支來使用
	switch:{}
4.switch 後面也可以直接宣告/定義一個變數,以分號結尾(不推薦)
	switch grade:=90;{}
5.switch穿透-fallthough,
	如果在case語句塊後增加fallthrough,會繼續執行下一個case,
	var num int = 20
	switch num{
        case 10:
            fmt.Print('ok')
            fallthrough  //預設只能穿透一層,執行case 30
        case 30:
        	fmt.Print('1')
         // case不需寫break,預設情況下執行case語句以後,就跳出switch控制語句
        	break   
        default:    // 不是必須的,
        	fmt.Print('2')
    	}
6.type-switch:
	// 判斷某個interface 變數中實際指向的變數型別
	var x interface{}
	var y = 10.0
	x = y
    switch i:=x.(type){
        case nil:
            fmt.Print('x的型別是:%T',i)
        case int:
            fmt.Print('x的型別是整型')	
    }


7.switch 和 if 區別

  1. 如果判斷的具體數值不多,而且符合整數、浮點數、字元、字串這幾種型別。建議使用swtich語句,簡潔高效。

  2. 其他情況:對區間判斷和結果為bool型別的判斷,使用if, if的使用範圍更廣。

3.迴圈結構

  • golang中沒有while和do..while的語法,需要通過for迴圈實現

1.for迴圈結構

for 迴圈變數初始化 ;迴圈條件 ; 迴圈變數迭代{
	迴圈執行語句(語句)
} 
// 注意省略情況
1. 省略初始化迴圈變數、迴圈變數迭代: //相當於while迴圈 
     for i > 10{}
             迴圈變數初始化
       
        說明:1.此for迴圈是一個無限迴圈
             2.break就是來跳出for語句
2.全部省略   // 無限迴圈
	1.保留分號
		for ; ;{
                迴圈執行語句
                break
            } 
	2.不保留分號  
		// 實現 while
		// 實現 do - while
		for{
                迴圈執行語句
                break
            }

2.實現while 迴圈

 for{
    if 迴圈條件表示式{
        break //跳出for迴圈
          }
    迴圈操作(語句)
    迴圈變數迭代
        }

3.實現 do - while

迴圈變數初始化
 for{
     迴圈操作(語句)
     迴圈變數的迭代
     if 迴圈條件表示式{
         break  //跳出for迴圈
      }
  }
 1.先執行,再判斷,因此至少執行一次
 2.迴圈條件成立後,就會執行break,跳出for 迴圈,結束迴圈

4.構成

1.初始語句

  開始迴圈執行的語句, 第一次迴圈前執行的語句,一般使用初始語句執行變數初始化,如果變數在此處被宣告,其作用域將被侷限在這個 for 的範圍內。 

初始語句可以被忽略,但是初始語句之後的分號必須要寫, 

2.條件表示式

控制是否迴圈的開關, 每次迴圈開始前都會計算條件表示式,

表示式為 true     :則迴圈繼續,

表示式為False   :結束迴圈

表示式忽略        :後預設形成無限迴圈。 

3.結束語句

在結束每次迴圈前執行的語句,如果迴圈被 break、goto、return、panic 等語句強制退出,結束語句不會被執行。

5.多重迴圈控制

  1. 一個迴圈放在另一個迴圈體內,就形成了巢狀迴圈,建議一般使用兩層,最多不適用三層
  2. 實質就是內層迴圈的迴圈條件為false時,才會跳出內層迴圈,才結束外層的 當次 迴圈
  3. 外層迴圈m次,內層迴圈n次,則內層迴圈體需要執行 m * n次
  4. 編譯後先易後難,將一個複雜的問題分解為簡單的問題,

6.跳出迴圈

1. break

  • 一般都是用來跳出 forswitch 語句。在 Go 中也可以在 select 語句中使用 break
  • 跳出 當前(最近) 的 for 迴圈或者switch語句
  • 跳出標籤
// break後面可以指定標籤,跳出標籤對應的for迴圈
// 為不帶標籤的break只能終止最內層(innermost)的迴圈,如果像終止外部的迴圈,就得用標籤了:

lable 2:
for i := 0;i < 4; i++{
	for  j := 0;j < 4;j++{  //設定一個lable1  
		if j == 2{
		break lable2         //跳出lable2下面對應的for迴圈
		}
	} 
}

  • 語句不能跨越函式邊界。
// 跨越邊界會報錯	 break is not in a loop, switch, or select

2. fallthrough

2.contine

  1. 跳出本次迴圈,執行下一次迴圈

  2. 可以通過標籤指明要跳過的哪一層迴圈,調到標籤對應的 for 迴圈處

    here:
    for i:=0;i<4;i++{
        for j:=1;j<4;j++{
            if j==2{
                continue here
            }
           fmt.Print("i=",i,"j=",j)
        }
    }
    /*
    i= 0 j= 1
    i= 1 j= 1
    i= 2 j= 1
    i= 3 j= 1
    */
    
    

3.goto

  1. 可以無條件跳到程式中指定的行,接著往下執行
  2. goto語句通常與條件語句配合使用。可用來實現條件轉移,跳出迴圈體等功能。
  3. 不建議使用,以免造成程式流程的混亂,使理解和除錯程式都產生困難
if n > 20{
goto lable2
}
lable2:

4.return

  • 如果return是在普通的函式,則表示跳出當前所在的方法或函式,即不再執行函式中return後面程式碼,也可以理解成終止函式

  • 如果return是在main函式,表示終止main函式,也就是說終止程式。

  • 1、無返回型別

    • return語句不能返回任何值。
  • 2、有返回型別

    • 返回值可以顯示地寫在return的後面,每個表示式必須是單值的

      func simpleF() int {
      	return 2
      }
      func complexF1() (re float64, im float64) {
      	return -7.0, -4.0
      }
      
    • return語句中的表示式列表可以是對返回多隻函式的呼叫

      func complexF2() (re float64, im float64) {
          return complexF1()
      }
      
    • 如果函式的返回型別引數指定了名字,則 return 可以返回空。這些返回型別引數就像本地變數一樣。

      // 所有的結果值在函式的開始時都被初始化為它們的零值
      func complexF3() (re float64, im float64) {
      	re = 7.0
      	im = 4.0
      	return	// 沒有引數的 return 語句返回各個返回變數的當前值。這種用法被稱作“裸”返回。
      }
      func (devnull) Write(p []byte) (n int, _ error) {
      	n = len(p)
      	return
      }
      
      func f(n int) (res int, err error) {
      	if _, err := f(n-1); err != nil {
      		return  // invalid return statement: err is shadowed ,編譯器不允許返回空??
      	}
      	return
      }
       // 編譯器不知道你具體會在哪裡返回,這個要執行時才能確定,所以,你最外面沒有返回,編譯器就認為你錯了,語法不通過 
      
      // 儘量不要使用 func test() error{} 這種哦最後不能裸返回,有點兒糟心
      

跳轉