Video address of this article

How can I use a function

1 is created inside the function
// $GOROOT/src/runtime/print.go func hexdumpWords(p, end uintptr, mark func(uintptr) byte) { p1 := func(x uintptr) { var buf [2 * sys.PtrSize]byte for i := len(buf) - 1; i >= 0; i-- { if x&0xF < 10 { buf[i] = byte(x&0xF) + '0' } else { buf[i] = byte(x&0xF) - 10 + 'a' } x >>= 4 } gwrite(buf[:]) } . }Copy the code

Inside the hexdumpWords function, the variable P1 is assigned by an anonymous function.

2 as type

Use functions to customize types

// $GOROOT/src/net/http/server.go
type HandlerFunc func(ResponseWriter, *Request)
Copy the code
3 Store it in a variable
// $GOROOT/src/runtime/vdso_linux.go func vdsoParseSymbols(info *vdsoInfo, version int32) { if ! info.valid { return } apply := func(symIndex uint32, k vdsoSymbolKey) bool { sym := &info.symtab[symIndex] typ := _ELF_ST_TYPE(sym.st_info) bind := _ELF_ST_BIND(sym.st_info) . *k.ptr = info.loadOffset + uintptr(sym.st_value) return true } ... }Copy the code
4 is passed to the function as an argument
$GOROOT/src/time/sleep.go

func AfterFunc(d Duration, f func()) *Timer {
        t := &Timer{
                r: runtimeTimer{
                        when: when(d),
                        f:    goFunc,
                        arg:  f,
                },
        }
        startTimer(&t.r)
        return t
}
Copy the code
5. Return from the function as a return value
// $GOROOT/src/strings/strings.go
func makeCutsetFunc(cutset string) func(rune) bool {
        if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
                return func(r rune) bool {
                        return r == rune(cutset[0])
                }
        }
        if as, isASCII := makeASCIISet(cutset); isASCII {
                return func(r rune) bool {
                        return r < utf8.RuneSelf && as.contains(byte(r))
                }
        }
        return func(r rune) bool { return IndexRune(cutset, r) >= 0 }
}
Copy the code

The special use of binary functions as “first-class citizens”

1. Perform an explicit transformation to a function like an integer variable
Func Welcome(w http.responseWriter, r * http.request) {FMT.Fprintf(w, "Welcome to the Go language! \n") } func main() { http.ListenAndServe(":8080", http.HandlerFunc(Welcome)) } // $GOROOT/src/net/http/server.go func ListenAndServe(addr string, handler Handler) error { server := &Server{Addr: addr, Handler: handler} return server.ListenAndServe() }Copy the code

You can see the second parameter to the ListenAndServe method, handler, where the handler parameter is of type HTTP.Handler interface.

// $GOROOT/src/net/http/server.go
type Handler interface {
        ServeHTTP(ResponseWriter, *Request)
}
Copy the code

The http.handler interface has only one ServeHTTP method, which we can see is prototyped as func(http.responseWriter, * http.request), exactly like the Welcome prototyped.

// $GOROOT/src/net/http/server.go

type HandlerFunc func(ResponseWriter, *Request)

// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
        f(w, r)
}
Copy the code

HandlerFunc implements the ServeHTTP method, which implements the Handler interface. The Welcome function is explicitly converted to the HandlerFunc type.