
函数类型也分两种,一种是函数字面量类型(未命名类型),另一种是函数命名类型。
函数字面量类型函数字面量类型的语法表达格式是 func(inputTypeList)OutputTypeList,“有名函数”和“匿名函数”的类型都属于函数字面量类型,有名函数的定义相当于初始化一个函数字面量类型后将其赋值给一个函数名变量,“匿名函数”的定义也是直接初始化一个函数字面量类型,只是没有绑定到一个具体函数名变量上。从 Go 类型系统的角度来看,“有名函数”和“匿名函数”都是函数字面量类型的实例。
函数命名类型从前面章节知道可以使用 type NewType oldType 语法定义一种新类型,这种类型都是命名类型,同理可以使用该方法定义一种新类型——函数命名类型,简称函数类型,例如:
type NewFuncType Funcliteral
依据Go语言类型系统的概念,NewFuncType 为新定义的函数命名类型,Funcliteral 为函数字面量类型,Funcliteral 为函数类型 NewFuneType 的底层类型,当然也可以使用 type 在一个函数类型中再定义一个新的函数类型,这种用法在语法上是允许的,但很少这么使用,例如:type NewFuncType oldFuncType
函数签名有了上面的基础,函数签名就比较好理解了,所谓“函数签名”就是“有名函数”或“匿名函数”的字面量类型,所以有名函数和匿名函数的函数签名可以相同,函数签名是函数的“字面量类型”,不包括函数名。函数声明Go语言没有C语言中函数声明的语义,准确地说,Go 代码调用 Go 编写的函数不需要声明,可以直接调用,但 Go 调用汇编语言编写的函数还是要使用函数声明语句,示例如下。
//函数声明=函数名+函数签名
//函数签名
func (inputTypeList)OutputTypeList
//函数声明
func Funcname (inputTypeList)OutputTypeList
//有名函数定义,函数名是add//add 类型是函数字面量类型 func(int,int) intfunc add(a,b int) int { return a+b}//函数声明语句,用于 Go 代码调用汇编代码func add(int,int) int//add 函数的签名,实际上就是 add 的字面量类型func (int,int) int//匿名函数不能独立存在,常作为函数参数、返回值,或者赋值给某个变量//匿名函数可以直接显式初始化//匿名函数的类型也是函数字面量类型 func (int,int) intfunc (a,b int) int { return a+b}//新定义函数类型ADD//ADD 底层类型是函数字面量类型 func (int,int) inttype ADD func (int,int) int//add 和 ADD 的底层类型相同,并且 add 是字面量类型//所以 add 可直接赋值给 ADD 类型的变量 gvar g ADD = addfunc main() { f := func(a,b int) int { return a + b } g(1,2) f(1,2) //f 和 add 的函数签名相同 fmt.Printf("%T\n",f) // func(int,int) int fmt.Printf("%T\n",add) // func(int,int) int}前面谈到字面量类型是一种未命名类型 (unnamed type),其不能定义自己的方法,所以必须显式地使用 type 声明一个有名函数类型,然后为其添加方法,通常说的函数类型就是指有名函数类型,“函数签名”是指函数的字面量类型,在很多地方把函数类型和函数签名等价使用,这是不严谨的。由类型转换的规则可知,这两种类型的底层类型相同,并且其中一个是字面量类型,二者是可以相互转换的,下面来看一下经典的 http 标准库对函数类型的实现,进一步理解这种用法。
//src/net/http/server.go//定义一个有名函数类型 HandlerFunetype HandlerFunc func(ResponseWriter,*Request)//为有名的函数类型添加方法//这是一种包装器的编程技巧//Servehttp calls f(w,r).func (f HandlerFunc) Servehttp(w ResponseWriter,r *Request) { f(w,r)}//函数类型 HandlerFunc 实现了接口 Handler 的方法type Handler interface { Servehttp(ResponseWriter,*Request)}func (mux *ServeMux) Handle(pattern string,handler Handler)//所以 HandlerFunc 类型的交量可以传递给 Handler 接口变量func (mux *ServeMux) HandleFune (pattern string,handler func (ResponseWriter,*Request)) { mux.Handle(pattern,HandlerFunc(handler))}通过 http 标准库里面对于函数类型的使用,我们可以看到函数类型的如下意义:函数也是一种类型,可以在函数字面量类型的基础上定义一种命名函数类型。有名函数和匿名函数的函数签名与命名函数类型的底层类型相同,它们之间可以进行类型转换。可以为有名函数类型添加方法,这种为一个函数类型添加方法的技法非常有价值,可以方便地为一个函数增加“拦截”或“过滤”等额外功能,这提供了一种装饰设计模式。为有名函数类型添加方法,使其与接口打通关系,使用接口的地方可以传递函数类型的变量,这为函数到接口的转换开启了大门。 总结
以上是内存溢出为你收集整理的Go语言函数类型全部内容,希望文章能够帮你解决Go语言函数类型所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)