函數(shù)像其他值一樣揍庄,擁有類型吧慢,可以被賦值給其他變量,傳遞給函數(shù)笆制,從函數(shù)返回除秀。
函數(shù)類型的零值是nil糯累。調(diào)用值為nil的函數(shù)值會(huì)引起panic錯(cuò)誤:
var f func(int) int
f(3) // 此處f的值為nil, 會(huì)引起panic錯(cuò)誤
函數(shù)值可以與nil比較:
var f func(int) int
if f != nil {
f(3)
}
但是函數(shù)值之間是不可比較的,也不能用函數(shù)值作為map的key册踩。
package main
import "fmt"
// 簽名 func(int, int) int
// 簽名是由函數(shù)形參類型 返回值類型組成
func add(a, b int) int {
return a + b
}
func addN(a, b int, arg ...int) int {
return 0
}
// 函數(shù)可以傳遞給函數(shù)
// callback 格式化 將傳遞的數(shù)據(jù)按照每行打印還是按照一行按|分割打印
func print(callback func(...string), args ...string) {
fmt.Println("print函數(shù)輸出:")
callback(args...)
}
func list(args ...string) {
for i, v := range args {
fmt.Println(i, ":", v)
}
}
func main() {
fmt.Printf("%T\n", add)
// f := add
var f func(int, int) int = add // 簽名一樣泳姐,可以賦值
// var f func(int, int) int = addN 簽名不一樣,不可以賦值
fmt.Printf("%T\n", f)
fmt.Println(f(1, 4))
// 函數(shù)可以傳遞給函數(shù)調(diào)用
print(list, "A", "C", "E")
// 匿名函數(shù)
sayHello := func(name string) {
fmt.Println("Hello", name)
}
// 調(diào)用匿名函數(shù)
sayHello("wpfs")
//定義匿名函數(shù)并且調(diào)用
func(name string) {
fmt.Println("Hi", name)
}("wpfs")
values := func(args ...string) {
for _, v := range args {
fmt.Println(v)
}
}
print(values, "A", "B", "C")
print(func(args ...string) {
for _, v := range args {
fmt.Print(v, "\t")
}
fmt.Println()
}, "A", "C", "E")
}
匿名函數(shù)
不需要定義名字的函數(shù)叫做匿名函數(shù)暂吉,常用做幫助函數(shù)在局部代碼塊中使用或作為其他函數(shù)的參數(shù)胖秒。
匿名函數(shù)又叫閉包缎患, 是指在函數(shù)內(nèi)定義的匿名函數(shù)引用外部函數(shù)的變量,只要匿名函數(shù)繼續(xù)使用則外部函數(shù)賦值的變量不被自動(dòng)銷毀阎肝。
package main
import "fmt"
func main() {
// 子作用域可以調(diào)用父作用域的變量
name := "wpfs"
add2 := func(n int) int {
return n + 2
}
add10 := func(n int) int {
return n + 10
}
fmt.Println(add2(3))
fmt.Println(add10(3))
func() {
fmt.Println(name)
}()
// 閉包挤渔,函數(shù)內(nèi)部調(diào)用外部的變量
addbase := func(base int) func(int) int {
return func(n int) int {
return base + n
}
}
add8 := addbase(8)
fmt.Printf("%T\n", add8)
fmt.Println(add8(2))
fmt.Println(addbase(100)(2))
}