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

溫馨提示×

溫馨提示×

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

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

go語言中函數與方法是什么

發布時間:2021-10-14 17:01:40 來源:億速云 閱讀:112 作者:柒染 欄目:編程語言

go語言中函數與方法是什么,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

  如果你遇到沒有函數體的函數聲明,表示該函數不是以Go實現的。

  package math

  func Sin(x float64) float //implemented in assembly language

  如果為函數的每一個返回值都設置變量名,則會以相應的零值初始化,且在該函數的return語句中省略操作數,這種用法稱之為 bare return。

  go中的錯誤處理,習慣上是先進行一系列的初始化檢查,將處理失敗邏輯的代碼先行處理,然后才是函數的實際邏輯,這樣使得代碼更簡潔,避免過多的層級結構。

  函數定義時,可以使用函數類型作為參數,也可以作為返回類型,是不是有點類似委托,從而實現閉包。此外還有匿名函數,是不是類似于lambda表達式。strings.Map 函數可以拿來試驗。

  func squares() func() int {

  var x int

  return func() int {

  x++

  return x * x

  }

  }

  func main() {

  f := squares()

  fmt.Println(f()) // "1"

  fmt.Println(f()) // "4"

  fmt.Println(f()) // "9"

  fmt.Println(f()) // "16"

  }

  匿名函數和squares中,存在變量引用。這就是函數值屬于引用類型和函數值不可比較的原因。Go使用閉包(closures)技術實現函數值,Go程序員也把函數值叫做閉包。

  注意golang圣經中匿名函數一節中的例子程序。

  go語言的可變參函數非常好用,你可以傳遞多個同類型參數,也可以直接傳入一個該類型的切片(注意傳入切片時要使用...標記,我想應該是為了同切片參數區分吧,畢竟兩者還是有些不同的),如果想要使用不同類型的變參,那么使用萬能的 interfac{} ,函數體內像解析切片一樣解析這個變參就好了。

  直到包含該defer語句的函數執行完畢時,defer后的函數才會被執行,不論包含defer語句的函數是通過return正常結束,還是由于panic導致的異常結束。你可以在一個函數中執行多條defer語句,它們的執行順序與聲明順序相反

  var mu sync.Mutex

  var m = make(map[string]int)

  func lookup(key string) int {

  mu.Lock()

  defer mu.Unlock()

  return m[key]

  }

  調試復雜程序時,defer機制也常被用于記錄何時進入和退出函數。

  func bigSlowOperation() {

  defer trace("bigSlowOperation")() // don't forget the

  extra parentheses

  // ...lots of work…

  time.Sleep(10 * time.Second) // simulate slow

  operation by sleeping

  }

  func trace(msg string) func() {

  start := time.Now()

  log.Printf("enter %s", msg)

  return func() {

  log.Printf("exit %s (%s)", msg,time.Since(start))

  }

  }

  我們只需要首先命名double的返回值,再增加defer語句,我們就可以在double每次被調用時,輸出參數以及返回值。

  func double(x int) (result int) {

  defer func() { fmt.Printf("double(%d) = %d\n", x,result) }()

  return x + x

  }

  _ = double(4)

  // Output:

  // "double(4) = 8"

  為了方便診斷問題,runtime包允許程序員輸出堆棧信息。在下面的例子中,我們通過在main函數中延遲調用printStack輸出堆棧信息。

  io/ch6/defer2

  func main() {

  defer printStack()

  f(3)

  }

  func printStack() {

  var buf [4096]byte

  n := runtime.Stack(buf[:], false)

  os.Stdout.Write(buf[:n])

  }

  不能為一個結構體定義同名的字段名和方法名,有點奇怪。

  函數指針:go里其實也是有函數指針的,下面用go語言實現表驅動模式。

  package main

  import (

  "fmt"

  )

  func add(a int, b int) int {

  return a + b

  }

  func sub(a int, b int) int {

  return a - b

  }

  func main() {

  fm := make(map[int]func(int, int) int)

  fm[1001] = add

  fm[1002] = sub

  protocol := 2001

  i := 1

  j := 2

  if func_handle, ok := fm[protocol]; ok {

  println(func_handle(i, j))

  } else {

  fmt.Printf("protocol: %d not register!", protocol)

  }

  }

  返回局部變量指針:

  不同于 C 語言,GO 的函數可以返回局部變化指針,且編譯器會通過逃逸分析(escape analysis)來決定是否在堆上分配內存。

  編譯時可以通過 -gcflags "-l -m" 參數來禁用函數內聯,函數內聯會對內存分配有一些影響,具體不清楚。

  函數參數沒有所謂的引用傳遞,都是值傳遞的,區別只是傳遞的是拷貝對象還是指針而已。在 C 語言中,一般推薦傳遞指針參數來避免復制對象提升效率。

  但在 go 中,被復制的指針會延長目標對象的生命周期,還可能導致它被分配到堆上,則性能消耗要加上堆內存分配和垃圾回收的成本,而在棧上復制小對象其實非常快,所以如果不是特別大的對象或確實需要修改原對象,一般不需要傳指針參數。在并發編程中,也提倡使用不可變對象(只讀或復制),可以消除數據同步的麻煩。

  如下就會在堆上分配內存,編譯時通過 -gcflags "-m" 可查看匯編代碼:

  func test(p *int) {

  go func() {

  println(p)

  }()

  }

  func main() {

  x := 100

  p := &x

  test(p)

  }

  使用傳出參數,推薦使用返回值,也可以使用二級指針:

  func test(p **int) {

  x := 100

  *p = &x

  }

  func main() {

  var p *int

  test(&p)

  println(*p)

  }

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

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

AI

天津市| 平乐县| 山阴县| 景谷| 宜春市| 贡嘎县| 宁武县| 高邮市| 逊克县| 香港| 华阴市| 桃江县| 武平县| 杭州市| 肃宁县| 昭平县| 曲阳县| 北宁市| 苍梧县| 萨嘎县| 德令哈市| 桂阳县| 波密县| 闻喜县| 寻乌县| 项城市| 炉霍县| 大英县| 琼海市| 湘阴县| 绩溪县| 淮安市| 柏乡县| 锦屏县| 甘南县| 霍邱县| 平陆县| 临城县| 和林格尔县| 开阳县| 武陟县|