函数也可以赋值给变量,存储在数组,切片,映射中,也可以作为参数传递给函数或作为函数返回值进行返回。函数的参数,数量,对应类型,以及函数返回值称为函数的签名。
1函数赋值给变量
- 示例:
来看这样的示例.
定义了add函数,而后在main中将add赋值给f,而后打印出add和f的类型
package main
import "fmt"
func add(a,b int)int{
return a + b
}
func main(){
fmt.Printf("%Tn",add)
f := add
fmt.Printf("%T",f)
}
运行
[root@LinuxEA /opt/Golang/work3]# go run add5.go
func(int, int) int
func(int, int) int
当赋值后,f和add都是函数类型。
只有相同的函数签名才能赋值,如果函数签名的类型不一样就不可以赋值
package main import "fmt" func add(a,b int)int{ return a + b } func add1(a,b int,args ...string) int { return 0 } func main(){ fmt.Printf("%Tn",add) fmt.Printf("%Tn",add1) var f func(int,int) int = add1 fmt.Printf("%T",f) }
运行
[root@LinuxEA /opt/Golang/work3]# go run add6.go # command-line-arguments ./add6.go:13:6: cannot use add1 (type func(int, int, ...string) int) as type func(int, int) int in assignment
1.2函数传递
函数可以赋值给变量,那也就意味着可以能够进行作为实参进行传递。现在我们定义两个函数进行传参数。
通过函数定义一个行参的函数类型,并把函数通过行参和实参进行传递。
- print函数
先定义一个print函数,传递一个callback函数,
func print(callback )
callback函数用来格式化,将传递的数据按照每行打印,按|竖线分割打印。
这里使用可变参数,这里之所以使用func(...string)
,是因为这里传递是一个函数,在print中的名称是callback。而对于print也是用一个 可变的string的行参。
func print(callback func(...string),args ...string) {}
这也就意味着callback可以接受任意多个字符串函数的变量。
并且进行callback还需要进行解包callback(args...)
,如下:
func print(callback func(...string),args ...string) {
fmt.Println("println函数:")
callback(args...)
}
- list函数
再定义一个相同函数签名的list函数
func list(args ...string){}
我们知道,相同函数签名是可以进行赋值的。
并且对args进行遍历
func list(args ...string){
for i,v := range args {
fmt.Println(i,":",v)
}
}
在main中进行调用
func main(){
print(list,"A","C","E")
}
如下:
package main
import "fmt"
func print(callback func(...string),args ...string) {
fmt.Println("println函数:")
callback(args...)
}
func list(args ...string){
for i,v := range args {
fmt.Println(i,":",v)
}
}
func main(){
print(list,"A","C","E")
}
当在main中的print函数中调用list的时候,list会传递给callback,而"A","C","E"
会传递到print的args里面。callback在使用解包将"A","C","E"
传递到list的args中进行遍历打印
[root@LinuxEA /opt/Golang/work3]# go run add7.go
println函数:
0 : A
1 : C
2 : E
1.3匿名函数
如果一个函数只使用了一次,就可以定义一个匿名函数。匿名函数直接定义一个函数的变量等于一个函数。
- 示例
定义一个匿名函数,行参名称是name,string类型,而后打印name,赋值给sayHello,如下:
sayHello := func(name string) {
fmt.Println("hello",name)
}
调用sayHello如下:
sayHello("mark")
代码块
package main
import "fmt"
func main(){
sayHello := func(name string) {
fmt.Println("hello",name)
}
sayHello("mark")
}
运行
[root@LinuxEA /opt/Golang/work3]# go run add8.go
hello mark
- 示例2
当然,我们也可以在定义的同时,直接使用。如下:
func(name string) {
fmt.Println("hello",name)
}("mark")
如下:
package main
import "fmt"
func main(){
func(name string) {
fmt.Println("hello",name)
}("mark")
}
运行
[root@LinuxEA /opt/Golang/work3]# go run add9.go
hello mark
- 示例3
如下:
package main
import "fmt"
func print(callback func(...string),args ...string) {
fmt.Println("println函数:")
callback(args...)
}
func list(args ...string){
for i,v := range args {
fmt.Println(i,":",v)
}
}
func main(){
print(list,"A","C","E")
}
将list函数写成匿名函数进行调用
package main
import "fmt"
func print(callback func(...string),args ...string) {
fmt.Println("println函数:")
callback(args...)
}
func main(){
list := func(args ...string){
for i,v := range args {
fmt.Println(i,":",v)
}
}
print(list,"A","C","E")
}
运行
[root@LinuxEA /opt/Golang/work3]# go run add10.go
println函数:
0 : A
1 : C
2 : E
甚至可以在进行修改
- 在调用函数的时候使用匿名函数传递进去
package main
import "fmt"
func print(callback func(...string),args ...string) {
fmt.Println("println函数:")
callback(args...)
}
func main(){
print(func(args ...string){
for i,v := range args {
fmt.Println(i,":",v)
}
},"A","C","E")
}
运行
[root@LinuxEA /opt/Golang/work3]# go run add11.go
println函数:
0 : A
1 : C
2 : E