Go 語言程序設計——過程式編程(5)

閉包

  • 閉包就是一個函數 “捕獲” 了和它在同一作用域的其他常量和變量
  • 閉包被調用的時候雹食,不管在程序說明地方調用淹父,閉包能夠使用這些常量或者變量
  • 閉包不關心這些捕獲了的變量和常量是否超出了作用域躁劣,所以只要閉包還在使用七婴,變量就還存在
  • Go 語言中醒第,所有匿名函數(Go 語言規(guī)范中稱之為函數字面量)都是閉包
  • 閉包和普通函數的區(qū)別是閉包沒有名字(所以 func 關鍵字后面緊接著左括號)
  • 閉包的一種用法是利用包裝函數來為被包裝的函數預定義一到多個參數
  • 例子(給大量文件增加不同的后綴):
addPng := func(name string) string { return name + ".png" }
addJpg := func(name string) string { return name + ".jpg" }
fmt.Println(addPng("filename"), addJpg("filename"))
  • 現實環(huán)境中我們常用到一個工廠函數(factory function)供置,工廠函數返回一個函數:
func MakeAddSuffix(suffix string) func(string) string {
  return func(name string) string {
    if !strings.HasSuffix(name, suffix) {
      return name + suffix
    }
    return name
  }
}

遞歸函數

  • 遞歸函數就是調用自己的函數
  • 互相遞歸函數就是互相調用對方的函數
  • 遞歸函數通常有相同的結構:一個跳出條件一個遞歸體
  • 跳出條件就是一個條件語句况凉,例如 if 語句谚鄙,根據傳入的參數判斷是否需要停止遞歸
  • 遞歸體是函數自身所做的一些處理,包括最少也得調用自身一次(調用它互相遞歸的另一個函數體)
  • 遞歸調用時所傳入的參數一定不能和當前函數傳入的一樣刁绒,在 跳出條件 里還會檢查是否可以結束遞歸
  • 遞歸函數非常便于實現遞歸的數據結構例如 二叉樹
  • 遞歸函數對于數值計算而言可能會性能比較低下
  • 常規(guī)遞歸函數例子:
for n := 0; n < 20; n++ {
  fmt.Print(Fibonacci(n), " ")
}
fmt.Println()

func Fibonacci(n int) int {
  if n < 2 {
    return n
  }
  return Fibonacci(n - 1) + Fibonacci(n - 2)
}
  • 互相遞歸函數的例子:
females := make([]int, 20)
males := make([]int, len(females))
for n := range females {
  females[n] = HofstadterFemale(n)
  males[n] = HofstadterMale(n)
}
fmt.Println("F", females)
fmt.Println("M", males)

func HofstadterFemale(n int) int {
  if n <= 0 {
    return 1
  }
  return n - HofstadterMale(HofstadterFemale(n - 1))
}
func HofstadterMale(n int) int {
  if n <= 0 {
    return 0
  }
  return n - HofstadterFemale(HofstadterMale(n - 1))
}
  • 函數開始處都有一個 跳出條件 用來確保遞歸能夠正常結束闷营,在遞歸發(fā)生的地方我們需要保證最終 跳出條件 會被滿足
  • Go 語言不需要預定義函數,Go 語言允許函數以任何順序定義
  • 能用循環(huán)的話知市,最好使用循環(huán)傻盟,循環(huán)的好處是可以減少調用的開銷

運行時選擇函數

  • Go 語言中,函數屬于第一類值嫂丙,也就是說娘赴,我們可以將它保存在一個變量里,這樣我們可以決定要執(zhí)行哪一個函數
  • 同一個函數可以有兩個或者多個不同的實現跟啤,在使用的時候創(chuàng)建就行了
使用映射和函數引用來制造分支
  • 例子:
var FunctionForSuffix = map[string]func(string) ([]string, error) {
  ".gz": GzipFileList,
  ".tar": TarFileList,
  ".tar.ga": TarFileList,
  ".tgz": TarFileList,
  ".zip": ZipFileList,
}

func ArchiveFileListMap(file string) ([]string, error) {
  if function, ok := FunctionForSuffix[Suffix(file)]; ok {
    return function(file)
  }
  return nil, errors.New("unrecognized archive")
}
  • 通過映射可以使事情變得條理清晰
  • 還可以動態(tài)地往映射里增加其他的項
  • 映射查詢的速度不會隨著項目的增加而降低
動態(tài)函數的創(chuàng)建
  • 例子:
var IsPalindrome func(string) bool
func init() {
  if len(os.Args) > 1 && (os.Args[1] == "-a" || os.Args[1] == "--ascii") {
    os.Args = append(os.Args[:1], os.Args[2:]...) // 去掉參數
    IsPalindrome = func(s string) bool { // 簡單的 ASCII 版本
      if len(s) <= 1 {
        return true
      }
      if s[0] != s[len(s) - 1] {
        return false
      }
      return IsPalindrome(s[1 : len(s) - 1])
    }
  } else {
    IsPalindrome = func(s string) bool { // 簡單的 ASCII 版本
    // 同前
    }
  }
}
  • 實際代碼被執(zhí)行完全取決于創(chuàng)建的是哪個版本的函數
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末诽表,一起剝皮案震驚了整個濱河市唉锌,隨后出現的幾起案子,更是在濱河造成了極大的恐慌竿奏,老刑警劉巖袄简,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異泛啸,居然都是意外死亡绿语,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門候址,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吕粹,“玉大人,你說我怎么就攤上這事岗仑∑ジ” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵赔蒲,是天一觀的道長泌神。 經常有香客問我良漱,道長舞虱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任母市,我火速辦了婚禮矾兜,結果婚禮上,老公的妹妹穿的比我還像新娘患久。我一直安慰自己椅寺,他們只是感情好,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布蒋失。 她就那樣靜靜地躺著返帕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪篙挽。 梳的紋絲不亂的頭發(fā)上荆萤,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音铣卡,去河邊找鬼链韭。 笑死,一個胖子當著我的面吹牛煮落,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼筝家,長吁一口氣:“原來是場噩夢啊……” “哼瑰钮!你這毒婦竟也來了殖蚕?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤沉迹,失蹤者是張志新(化名)和其女友劉穎嫌褪,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體胚股,經...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡笼痛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了琅拌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缨伊。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖进宝,靈堂內的尸體忽然破棺而出刻坊,到底是詐尸還是另有隱情,我是刑警寧澤党晋,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布谭胚,位于F島的核電站,受9級特大地震影響未玻,放射性物質發(fā)生泄漏灾而。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一扳剿、第九天 我趴在偏房一處隱蔽的房頂上張望旁趟。 院中可真熱鬧,春花似錦庇绽、人聲如沸锡搜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽耕餐。三九已至,卻和暖如春辟狈,著一層夾襖步出監(jiān)牢的瞬間肠缔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工上陕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留桩砰,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓释簿,卻偏偏與公主長得像亚隅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子庶溶,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內容