开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第9天,点击查看活动详情
函数字面量类型和函数命名类型
函数字面量类型:
通常我们可以见到“匿名函数“这个概念,与之相对应的是”有名函数“,这两种类型都属于函数字面量类型,只不过一个是绑定了函数名变量,一个没有绑定。 有名函数格式:func funcName(InputTypeList) OutPutTypeList 匿名函数格式:func (InputTypeList) OutPutTypeList 函数字面量类型:func (InputTypeList) OutPutTypeList
所以直观上来看,匿名函数是直接初始化了一个函数字面量类型,而有名函数不仅初始化了而且还将其赋给了一个函数名变量。 如:
//方法声明 = 方法名 + 方法签名(其实就是函数字面量类型)
func add(a,b int) int { //func (int, int)int是函数字面量类型
return a+b
}
函数命名类型:
Type NewFuncType FuncLiteral
type Add func (int, int) int
此时Add的函数命名类型是func (int, int) int,当然此时我们没有函数的处理逻辑。记住上面讲过函数声明时函数的字面量类型也是func (int, int)int。所以我们完全可以将add赋值给Add。
var Add = add
HTTP源码示例
查看http的server标准库Go代码,可以看出函数类型的精妙用法。
type HandlerFunc func(ResponseWriter, *Request)
//函数命名类型为 func(ResponseWriter, *Request) 没有返回值
// ServeHTTP calls f(w, r).
//为函数添加方法!!!!是一种装饰设计模式
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
//HandleFunc实现了Hadler接口的方法
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
//Handle参数列表中有接口变量
func (mux *ServeMux) Handle(pattern string, handler Handler) {
mux.mu.Lock()
defer mux.mu.Unlock()
if pattern == "" {
panic("http: invalid pattern")
}
if handler == nil {
panic("http: nil handler")
}
if _, exist := mux.m[pattern]; exist {
panic("http: multiple registrations for " + pattern)
}
if mux.m == nil {
mux.m = make(map[string]muxEntry)
}
e := muxEntry{h: handler, pattern: pattern}
mux.m[pattern] = e
if pattern[len(pattern)-1] == '/' {
mux.es = appendSorted(mux.es, e)
}
if pattern[0] != '/' {
mux.hosts = true
}
}
// HandleFunc registers the handler function for the given pattern.
// HandleFunc 类型的变量可以传递给Handler接口变量
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
if handler == nil {
panic("http: nil handler")
}
mux.Handle(pattern, HandlerFunc(handler))
}
总结
- 有名函数和匿名函数的函数字面量类型和函数命名类型相同,可以相互转换
- 函数也可以添加方法,为一个函数增加额外的小功能
- 函数添加方法实现接口,使得函数能够转换到接口
- 函数声明 = 函数名 + 函数字面量类型