今天使用net/http库做了一个简单的server. 遇到一个之前自己忽略的问题,觉得挺有意思,简单做一个笔记。
server通过调用
1 |
func ListenAndServe(addr string, handler Handler) error |
实现。需要传递一个Handler类型的接口进行request/response的处理。Handler接口定义如下:
1 2 3 |
type Handler interface { ServeHTTP(ResponseWriter, *Request) } |
一切都非常简单,于是花了一分钟,写了一个server:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package main import ( "fmt" "io" "log" "net/http" ) type MyServer struct { i int } func (myServer *MyServer) ServeHTTP(w http.ResponseWriter, request *http.Request) { io.WriteString(w, "Hello") fmt.Println(request.UserAgent()) } func main() { myServer := MyServer{1} err := http.ListenAndServe(":8080", myServer) if err != nil { log.Fatal("ListenAndServe: ", err) } } |
看似一切都没有问题的样子……但是却编译错误:
1 2 |
cannot use myServer (type MyServer) as type http.Handler in function argument: MyServer does not implement http.Handler (ServeHTTP method has pointer receiver) |
原来是类型不匹配的问题。具体来说,接收者的类型才是真正实现接口的类型。在本例中,接收者类型是*Myserver,myServer也必须是一个指针。fix后的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package main import ( "fmt" "io" "log" "net/http" ) type MyServer struct { i int } func (myServer *MyServer) ServeHTTP(w http.ResponseWriter, request *http.Request) { io.WriteString(w, "Hello") fmt.Println(request.UserAgent()) } func main() { myServer := &MyServer{1} err := http.ListenAndServe(":8080", myServer) if err != nil { log.Fatal("ListenAndServe: ", err) } } |