linuxea:go函数赋值传递和匿名函数(32)


函数也可以赋值给变量,存储在数组,切片,映射中,也可以作为参数传递给函数或作为函数返回值进行返回。函数的参数,数量,对应类型,以及函数返回值称为函数的签名。

I. 1函数赋值给变量

  • 示例:

来看这样的示例.

定义了add函数,而后在main中将add赋值给f,而后打印出add和f的类型

package main
import "fmt"
func add(a,b int)int{
    return a + b
}
func main(){
    fmt.Printf("%T\n",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("%T\n",add)
  fmt.Printf("%T\n",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

II. 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

III. 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
0 分享

您可以选择一种方式赞助本站

支付宝扫码赞助

支付宝扫码赞助

日期: 2020-11-10分类: Golang

标签: Golang

发表评论