funcparseNanoseconds(value string, nbytes int) (ns int, rangeErrString string, err error) { if value[0] != '.' { err = errBad return } if ns, err = atoi(value[1:nbytes]); err != nil { return } if ns < 0 || 1e9 <= ns { rangeErrString = "fractional second" return } // We need nanoseconds, which means scaling by the number // of missing digits in the format, maximum length 10. If it's // longer than 10, we won't scale. scaleDigits := 10 - nbytes for i := 0; i < scaleDigits; i++ { ns *= 10 } return }
一等公民
具有极大的灵活性
如果一门编程语言对某种语言元素的创建和使用没有限制,可以像对待值一样对待这种语言元素
可以存储在变量中,可以作为参数传递给函数,可以在函数内部创建并作为返回值从函数返回
特征
变量
1 2 3 4 5 6 7 8 9 10 11
var ( // 创建匿名函数并赋值给 myFprintf 变量 myFprintf = func(w io.Writer, format string, args ...interface{}) (int, error) { return fmt.Fprintf(w, format, args...) } )
// Output: // init opa // do something // clean up opa
闭包本质上是一个匿名函数(函数字面量),可以引用它的包裹函数中定义的变量
这些变量在包裹函数和匿名函数之间共享
Go 的闭包特性是建立在函数是一等公民的基础上
参数
time/sleep.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// AfterFunc waits for the duration to elapse and then calls f // in its own goroutine. It returns a Timer that can // be used to cancel the call using its Stop method. funcAfterFunc(d Duration, f func()) *Timer { t := &Timer{ r: runtimeTimer{ when: when(d), f: goFunc, arg: f, }, } startTimer(&t.r) return t }
类型
每个函数声明定义的函数,仅仅只是对应的函数类型的一个实例
基于函数类型来自定义类型
net/http/server.go
1 2 3 4 5
// The HandlerFunc type is an adapter to allow the use of // ordinary functions as HTTP handlers. If f is a function // with the appropriate signature, HandlerFunc(f) is a // Handler that calls f. type HandlerFunc func(ResponseWriter, *Request)
// cannot use greeting (type func(http.ResponseWriter, *http.Request)) as type http.Handler in argument to http.ListenAndServe: // func(http.ResponseWriter, *http.Request) does not implement http.Handler (missing ServeHTTP method) //_ = http.ListenAndServe(":18088", greeting)