go語言中支援函式、匿名函式和閉包,並且函式在go語言中屬於「一等公民」。
go語言中定義函式使用func
關鍵字,具體格式如下:
func 函式名(引數)(返回值)
其中:我們先來定義乙個求兩個數之和的函式:
func intsum(x int, y int) int
函式的引數和返回值都是可選的,例如我們可以實現乙個既不需要引數也沒有返回值的函式:
func sayhello()
定義了函式之後,我們可以通過函式名()
的方式呼叫函式。 例如我們呼叫上面定義的兩個函式,**如下:
func main()
注意,呼叫有返回值的函式時,可以不接收其返回值。
函式的引數中如果相鄰變數的型別相同,則可以省略型別,例如:
func intsum(x, y int) int
上面的**中,intsum
函式有兩個引數,這兩個引數的型別均為int
,因此可以省略x
的型別,因為y
後面有型別說明,x
引數也是該型別。
可變引數是指函式的引數數量不固定。go語言中的可變引數通過在引數名後加...
來標識。
注意:可變引數通常要作為函式的最後乙個引數。
舉個例子:
func intsum2(x ...int) intreturn
sum}
呼叫上面的函式:
ret1 :=intsum2()ret2 := intsum2(10
)ret3 := intsum2(10, 20
)ret4 := intsum2(10, 20, 30
)fmt.println(ret1, ret2, ret3, ret4)
//0 10 30 60
固定引數搭配可變引數使用時,可變引數要放在固定引數的後面,示例**如下:
func intsum3(x int, y ...int) intreturn
sum}
呼叫上述函式:
ret5 := intsum3(100)ret6 := intsum3(100, 10
)ret7 := intsum3(100, 10, 20
)ret8 := intsum3(100, 10, 20, 30
)fmt.println(ret5, ret6, ret7, ret8)
//100 110 130 160
本質上,函式的可變引數是通過切片來實現的。
go語言中通過return
關鍵字向外輸出返回值。
go語言中函式支援多返回值,函式如果有多個返回值時必須用()
將所有返回值包裹起來。
舉個例子:
func calc(x, y int) (int, int)
函式定義時可以給返回值命名,並在函式體中直接使用這些變數,最後通過return
關鍵字返回。
例如:
func calc(x, y int) (sum, sub int)
go語言中的defer
語句會將其後面跟隨的語句進行延遲處理。在defer
歸屬的函式即將返回時,將延遲處理的語句按defer
定義的逆序進行執行,也就是說,先被defer
的語句最後被執行,最後被defer
的語句,最先被執行。
舉個例子:
func main()輸出結果:
start
end3
21
由於defer
語句延遲呼叫的特性,所以defer
語句能非常方便的處理資源釋放問題。比如:資源清理、檔案關閉、解鎖及記錄時間等。
全域性變數
全域性變數是定義在函式外部的變數,它在程式整個執行週期內都有效。 在函式中可以訪問到全域性變數。
package mainimport
"fmt"//
定義全域性變數num
var num int64 = 10
func testglobalvar()
func main()
區域性變數
區域性變數又分為兩種: 函式內定義
func testlocalvar()
如果區域性變數和全域性變數重名,優先訪問區域性變數。
package mainimport
"fmt"//
定義全域性變數num
var num int64 = 10
func testnum()
func main()
語句塊內定義。
func testlocalvar2(x, y int)
//此處無法使用變數z
}
還有我們之前講過的for迴圈語句中定義的變數,也是只在for語句塊中生效:
func testlocalvar3()//此處無法使用變數i
}
函式可以作為變數進行傳遞:
func main()
函式還可以作為引數:
func add(x, y int) intfunc calc(x, y
int, op func(int, int) int) int
func main()
匿名函式就是沒有函式名的函式,匿名函式多用於實現**函式和閉包。
匿名函式的定義格式如下:
func(引數)(返回值)
立即執行函式:
func main() (10, 20)//
匿名函式定義完加()直接執行
}
func adder() func(int) int}func main()
變數f
是乙個函式並且它引用了其外部作用域中的x
變數,此時f
就是乙個閉包。 在f
的生命週期內,變數x
也一直有效。 閉包高階示例1:
func adder2(x int) func(int) int}func main()
閉包高階示例2:
func makesuffixfunc(suffix string) func(string) stringreturn
name
}}func main()
閉包高階示例3:
func calc(baseint) (func(int) int, func(int) int
) sub := func(i int) int
return
add, sub
}func main()
閉包其實並不複雜,只要牢記閉包=函式+引用環境
。
內建函式
介紹close
主要用來關閉channel
len用來求長度,比如string、array、slice、map、channel
new用來分配記憶體,主要用來分配值型別,比如int、struct。返回的是指標
make
用來分配記憶體,主要用來分配引用型別,比如chan、map、slice
用來追加元素到陣列、slice中
panic和recover
用來做錯誤處理
go語言中目前(go1.12)是沒有異常機制,但是使用panic/recover
模式來處理錯誤。panic
可以在任何地方引發,但recover
只有在defer
呼叫的函式中有效。 首先來看乙個例子:
func funca()func funcb()
func funcc()
func main()
輸出:func a
panic: panic inb
goroutine
1[running]:
main.funcb(...)
.../code/func/main.go:12
main.main()
.../code/func/main.go:20 +0x98
程式執行期間funcb中引發了panic導致程式崩潰,異常退出了。這個時候我們就可以通過recover將程式恢復回來,繼續往後執行。
func funca()
func funcb()
}()panic(
"panic in b")
}func funcc()
func main()
注意:
recover()
必須搭配defer
使用。
defer
一定要在可能引發panic
的語句之前定義。
go語言基礎 函式
函式 一 概念 函式,就是一段具有特殊功能的 二 作用 避免重複的 提高程式的擴充套件性 三 語法 1.先定義,也叫宣告 func 函式名 形參列表 引數名 引數型別 返回值 2.再呼叫 函式名一致,實參列表必須嚴格匹配形參 函式可以被多次呼叫,叫呼叫處。packagemain import fmt...
go語言基礎之init函式的介紹
1 init函式的介紹 示例 資料夾目錄如下 源 vi main.go 程式入口 package main 必須 import calc fmt 2 再執行這個init列印 func init func main vi src calc.go package calc import fmt 1 先執...
GO語言基礎之method
方法 method 1.go 中雖沒有 class,但依舊有 method 2.通過顯示說明 receiver 來實現與某個型別的組合 3.只能為同乙個包中的型別定義方法 4.receiver 可以是型別的值或者指標 5.不存在方法過載 6.可以使用值或指標來呼叫方法,編譯器會自動完成轉換 7.從某...