When check following code, got a doubt with type convert from function to interface.
Code
http_hello.go:
package main
import (
"fmt"
"log"
"net/http"
)
// hello http,
func helloHttp() {
// register handler,
http.Handle("/", http.HandlerFunc(helloHandler))
// start server,
err := http.ListenAndServe(":9090", nil)
if err != nil {
log.Fatal("ListenAndServe:", err)
}
}
// handler function - hello,
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, you've requested: %s
", r.URL.Path)
}
func main() {
helloHttp()
}
The above code works.
(Then I tried to write a small program to check is this a general feature, but it won't work, check following code)
func_to_intf.go:
package main
import (
"fmt"
)
// an interface,
type Adder interface {
add(a, b int) int
}
// alias of a function signature,
type AdderFunc func(int, int) int
// a simple add function,
func simpleAdd(a, b int) int {
return a + b
}
// call Adder interface to perform add,
func doAdd(a, b int, f Adder) int {
return f.add(a, b)
}
func funcToIntf() {
fa := AdderFunc(simpleAdd)
fmt.Printf("%#v, type: %T
", fa, fa)
a, b := 1, 2
sum := doAdd(a, b, fa)
fmt.Printf("%d + %d = %d
", a, b, sum)
}
func main() {
funcToIntf()
}
Output:
./func_to_intf.go:30:14: cannot use fa (type AdderFunc) as type Adder in argument to doAdd: AdderFunc does not implement Adder (missing add method)
Questions
-
http.HandlerFunc(helloHandler)
get a value of typehttp.Handler
, since that's whathttp.Handle()
expect, is that correct? - If yes, then means it convert a function into a value of an interface type, how did that happen?
- Is this a built-in feature of go?
I did a test (as infunc_to_intf.go
above), and seems not. - Or, is
http.HandlerFunc
's special implementation achieve that?
- Is this a built-in feature of go?
@Update - Summary
(Though the answer(s) addressed the questions pretty well, but after reviewing & more testing, there are several other go features required to totally erase the original doubt, as following.)
- Function type.
Function is value, and it has type.
Function type could be defined viatype
keyword on a function signature.
e.gtype AdderFunc func(int, int) int
- Type convertor
T(v)
on function.
Any function could be converted to a function type with the same signature, just viaT(v)
, use function type name asT
, and actual function asv
.
Then when the new value is called, the actual functionv
is called.
e.gfa := AdderFunc(simpleAdd)
(this is blur to me before asking the question, and that's one of the main reason I was confused).