go 流程控制及函數相關

流程控制

switch

  1. go語言中的case不僅可以基於常量進行判斷,也可以基於表達式進行判斷,不用寫break
  2. 一分支多值: case “1”,”2”
  3. 分支表達式:case 4>r &&r>2 // 這種條件下switch後不再跟判斷變量(無判斷目標)
  4. fallthrough關鍵字,執行完一個Case後會執行下一個case,不建議使用。

goto

  1. 可以退出多層循環 在循環中goto xxx,循環外xxx: 代碼
  2. 統一錯誤處理,在處理處均goto xxx,在進行處理處 xxx: 代碼

break

  1. 跳出指定循環

outloop:

       循環1

          循環2 {

break outloop

}

函數

  1. go語言函數本身可以作爲值傳遞
  2. 支持匿名函數和閉包
  3. 函數可以滿足接口

函數的返回值(支持多返回值)

  1. 同一類型返回值

func xxx() (int,int){

        return 1,2

}

  1. 帶有變量名的返回值

func xxx() (a,b int) {

        a=1

b=2   //或return a,2

return

}

同一種類型返回值和命名返回值兩種形式只能二選一,混用會發生編譯錯誤

函數變量

  1. go語言中函數也是一種類型func(),可以和其他類型一樣被保存在變量中。例如:

func fire(){

}

var f func()

f=fire

f()

匿名函數

定義

 func(參數列表) (返回參數列表) {

函數體

}

在定義時調用

func(參數列表) (返回參數列表) {

函數體

}(實參列表)

賦值給變量

f := func(參數列表) (返回參數列表) {

函數體

}

f(實參列表)//通過變量調用

作回調函數

func visit(list []int, f func(int)) {

       for _, value := range list {

              f(value)

       }

}

 

func main() {

       // 使用匿名函數打印切片內容

       visit([]int{1, 2, 3, 4, 5}, func(v int) {

              fmt.Println(v)

       })

}

實現操作封裝

func main() {

       flag.Parse()

       // 將匿名函數作爲map的鍵值,輸入不同的key,執行不同的鍵值

       var skill = map[string]func(){

              "fire": func() {

                     fmt.Println("chicken fire")

              },

              "run": func() {

                     fmt.Println("soldier run")

              },

              "fly": func() {

                     fmt.Println("angel fly")

              },

       }

 

       // *skillParam獲取命令行傳來的值,並在map中查找對應命令行參數指定的字符串的函數

       if f, ok := skill[*skillParam]; ok {

              f()

       } else {

              fmt.Println("skill not found")

       }

}

函數作爲接口調用

/* 函數實現接口 */

// 函數定義爲類型

type FuncCaller func(interface{}) //將func(interface{})定義爲FuncCaller類型

 

// 實現Invoker的Call

func (f FuncCaller) Call(p interface{}) { //FuncCaller的Call方法實現Invoker的Call方法

       // 調用f()函數本體

       f(p) // FuncCaller的Call方法被調用還需函數本體,需要函數本身進行邏輯處理

}

 

// FuncCaller無需被實例化,只需要將函數轉化爲FuncCall即可

       var in2 Invoker //聲明接口變量

       // 將匿名函數轉爲FuncCall類型,再賦值給接口

       in2 = FuncCaller(func(v interface{}) {

              fmt.Println("fron function", v)

       })

       // 使用接口調用 FuncCaller.Call,內部會調用函數本體

       in2.Call("hellp")

閉包

類似c++中的lambda表達式,函數是編譯時靜態的概念,閉包是運行時動態的概念

c++與c#爲閉包創建了一個類,被捕獲的變量在編譯時放到類的成員中,閉包在訪問被捕獲的變量時,實際上訪問的是閉包隱藏類的成員。

可變參數

v…T

  1. 一般放在函數列表的末尾
  2. v …[]T,表示類型是[]T,即擁有多個  T元素的T類型切片
  3. T爲可變參數的類型,當T爲interface{}時,傳入的可以是任意類型(比如fmt.Println()的實現)
  4. 獲取可變參數的類型s.(type)
  5. 在多個可變參數中傳遞參數:可變參數變量是一個包含所有參數的切片,如果要在多個可變參數中傳遞參數,可以在傳遞時在可變參數變量中默認添加“...”,將切片中的元素進行傳遞,而不是傳遞可變參數變量本身。可變參數使用...進行傳遞與切片間使用append連接是同一個特性

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章