91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Go語言中的函數

發布時間:2020-07-27 00:02:15 來源:網絡 閱讀:172 作者:小韓說課 欄目:編程語言

1 概述

函數,function,獨立的,用于實現具體功能的代碼塊。主要目的,是代碼的重用(重復使用),更好的管理代碼,模塊化開發。
函數通常使用參數和返回值,與調用者交互數據。參數給函數傳遞數據,返回值,函數將處理好的數據傳遞給調用者。
Go語言中函數被稱為一等公民(first-class)。意味著支持高階函數,支持匿名函數,支持閉包等特性,可以滿足接口等高級函數特性。

2 定義

語法:

定義:
func 函數名(形參列表)(返回值類型列表) {
  函數體,通常會有return語句,返回值
}
調用:
函數名(實參列表)

函數名:函數的標識符,用于找到函數,內部是一個指向函數代碼的地址。
形參列表:由變量和類型構成
返回值類型列表:函數返回值的類型,多個返回值需要指定多個。
函數體:實現函數功能的具體語句。
return語句:返回值語句

以上定的為命名函數,不能定義在其他函數內部。

3 參數

用于在調用函數時向函數傳遞數據。
實參,實際參數。調用時給的參數。指的是具有的特定實際數據的參數。
形參,形式參數。定義時使用的參數。指的是用來表示函數需要參數,而定義時參數是沒有任實際何數據的。
當調用時會發生使用實參為形參變量賦值的過程,稱為參數的傳遞。在函數的執行期間,形參是有具體數據的,形參當于函數內聲明的變量。

參數的傳遞,分為值傳遞,地址傳遞兩種方式。地址傳遞時,需要形參定義為指針類型,調用時需要取得地址傳參。示例代碼:

func funcTest(p1 int, p2 *int) {
  p1++
  *p2++
  fmt.Println(p1, *p2)
}
func main() {
  var (
    a1 = 42
    a2 = 42
  )
  funcTest(a1, &a2)
  // 參數賦值過程
  fmt.Println(a1, a2)
}
以上會輸出
43 43
42 43

值傳遞,函數會得到實參的一份拷貝。地址傳遞,函數會得到實參地址,這樣函數內通過地址對變量的修改,同時影響實參。

Go支持rest...不定數量參數,定義時將不定數量形參放在形參列表的最后定義,使用 ...Type的方式,演示:

定義:
func funcTest(op string, nums ...int) {
  fmt.Println(nums) // [4, 1, 55, 12], slice切片型數據
}
調用
funcTest("someOp", 4, 1, 55, 12)

接收到的參數為slice切片類型。

4 返回值

return語句用于生成返回值。需要在函數定義時確定返回值類型,支持多值返回。演示語法:

func funcTest() (int, string) {
  return 42, "Hank"
}

可以在定義時,聲明返回的變量。這個做法叫命名返回,演示為:

func funcTest() (num int, title string) {
  num = 42
  title = "Hank"
  return
}

不用return任何數據,直接return即可!

5 函數變量

函數可以看作一種特殊的指針類型,可以和其他類型一樣被保存在變量中。通過函數標識符和變量都可以訪問到該函數,演示如下:

func funcTest() {
  fmt.Println("func() type")
}
func main() {
  fmt.Printf("%T, (%v)\n", funcTest, funcTest)
  fn := funcTest
  fmt.Printf("%T, (%v)\n", fn, fn)
  funcTest()
  fn()
}
執行結果:
func(), (0x48fe20)
func(), (0x48fe20)
func() type
func() type

可見,函數標識符就是指向函數的指針。可以賦值給其他變量。

6 函數參數

函數也可以作為其他函數的參數來使用,演示如下:

func funcSuccess() {
}
func funcAsync(handle func()) {
  // 調用函數參數
  handle()
}
// 傳遞函數到其他函數
funcAsync(success)

這種回調函數的使用語法,在處理異步邏輯時十分有用。

7 匿名函數

可以定義匿名函數。可以將匿名函數保存到變量中,作為參數傳遞,或者立即調用。如果函數時臨時使用函數,則匿名函數是一個好選擇。示例語法:

賦值給變量
fn := func() {
}
fn()

// 作為參數
someFunc(func() {
  })

// 立即調用
func() {
  }()

8 閉包

由于匿名函數可以定義在其他函數內,同時變量的作用域為層疊的,也就是匿名函數可以會訪問其所在的外層函數內的局部變量。當外層函數運行結束后,匿名函數會與其使用的外部函數的局部變量形成閉包。示例代碼:

var fn func()
func outer() {
  v := 42
  fn = func() {
    v ++
    fmt.Print(v)
  }
}

outer()
fn() // 43

此例中,fn 對應的匿名函數與 outer() 的局部變量 v,就形成了閉包。

9 函數調用示意圖

var v = "global"
func funcTest(v) {
  v = "funcTest"
  fmt.Println(v)
}
func main() {
  v := "main"
  funcTest(v)
}

代碼編譯期間,會將函數代碼存放在內存代碼區。
函數被調用時,在運行期間會在函數運行棧區開辟函數棧,內部由局部變量標識符列表(就是局部變量),上層標識符列表引用等信息。直到運行結束,此空間才會被出棧,釋放。
函數內部調用了新函數,新函數的執行空間入棧,要等到新函數執行空間出棧,調用他的函數才會被出棧。
以上代碼的運行邏輯圖如下:
Go語言中的函數

10 遞歸調用

函數內部調用函數本身。稱之為遞歸調用。示例代碼:

func funcTest() {
  fmt.Println("run")
  funcTest()
}

定義實現遞歸調用函數時,通常需要定義一個出口。用來確定何時不再進行遞歸調用了。一旦滿足條件,則調用停止。例如:

func funcTest(v) {
  fmt.Println(v, "run")
  v ++
  if v <= 10 {
    funcTest()
  }
}

典型的應用有,樹狀菜單的處理,遍歷目錄,快速排序等。
遞歸調用的優勢是編碼簡單,與描述的業務邏輯保持一致。

完!
原文出自:小韓說課
微信關注:小韓說課
Go語言中的函數

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

托克托县| 贡觉县| 紫阳县| 龙游县| 秦皇岛市| 铁力市| 奉新县| 福清市| 阳信县| 安福县| 秀山| 彩票| 昂仁县| 辽中县| 岚皋县| 湖北省| 阿荣旗| 玉溪市| 张家港市| 饶平县| 北碚区| 绥阳县| 芜湖市| 墨江| 松阳县| 祁阳县| 宣威市| 盱眙县| 鸡西市| 莒南县| 邹城市| 五台县| 大名县| 建湖县| 通河县| 壶关县| 永平县| 长汀县| 页游| 成武县| 行唐县|