Ответ 1
Это:
type Handler interface {
ServeHTTP(*Conn, *Request)
}
говорит, что любой тип, который удовлетворяет интерфейсу Handler
, должен иметь метод ServeHTTP
. Вышеупомянутое будет внутри пакета http
.
type Counter int
func (ctr *Counter) ServeHTTP(c *http.Conn, req *http.Request) {
fmt.Fprintf(c, "counter = %d\n", ctr);
ctr++;
}
Это ставит метод в тип Counter, который соответствует ServeHTTP. Это пример, который отличается от следующего.
По моему мнению, тип "Счетчик" реализует интерфейс, поскольку он имеет метод, который имеет требуемую подпись.
Это правильно.
Следующая функция сама по себе не будет работать как Handler
:
func notFound(c *Conn, req *Request) {
c.SetHeader("Content-Type", "text/plain;", "charset=utf-8");
c.WriteHeader(StatusNotFound);
c.WriteString("404 page not found\n");
}
Остальная часть этого материала просто подгоняется выше, так что это может быть Handler
.
В следующем случае HandlerFunc
- это функция, которая принимает два аргумента, указатель на Conn
и указатель на Request
, и ничего не возвращает. Другими словами, любая функция, которая принимает эти аргументы и ничего не возвращает, может быть HandlerFunc
.
// Now we define a type to implement ServeHTTP:
type HandlerFunc func(*Conn, *Request)
Здесь ServeHTTP
- это метод, добавленный к типу HandlerFunc
:
func (f HandlerFunc) ServeHTTP(c *Conn, req *Request) {
f(c, req) // the receiver a func; call it
}
Все, что он делает, это вызов самой функции (f
) с указанными аргументами.
// Convert function to attach method, implement the interface:
var Handle404 = HandlerFunc(notFound);
В приведенной выше строке notFound
был включен в качестве допустимого для интерфейса для Handler
путем искусственного создания экземпляра типа из самой функции и превращения функции в метод ServeHTTP
для экземпляра. Теперь Handle404
можно использовать с интерфейсом Handler
. Это в основном своего рода трюк.