Любой тип может быть получателем. Например:
type X int
Здесь X
- это новый тип, и вы можете создать для него методы:
func (x X) method() {
// Do something with x
}
В Go функции похожи на любой другой тип , Поэтому, если у вас есть тип функции:
type F func()
Здесь F
- это новый тип, поэтому вы можете определить методы для него:
func (x F) method() {
x()
}
С помощью вышеуказанного объявления, теперь Вы можете вызвать value.method()
, если value
имеет тип F
.
a:=F(func() {fmt.Println("hey")})
a.method()
Здесь a
является переменной типа F
. F
имеет метод с именем method
, поэтому вы можете вызвать a.method
. Когда вы вызываете это, a.method
вызывает a
, что является функцией.
Возвращаясь к вашему примеру, appHandler
представляется типом функции:
type appHandler func(http.ResponseWriter, *http.Request)
Так любая функция с этой подписью может использоваться вместо appHandler
. Допустим, вы пишете такую функцию:
func myHandler(http.ResponseWriter, *http.Request) {
// Handle request
}
Вы можете передавать эту функцию везде, где запрашивается appHandler
. Тем не менее, вы не можете передать, где требуется Handler
, не написав такую структуру:
type myHandlerStruct struct{}
func (myHandlerStruct) ServeHTTP(w http.ResponseWriter, r *http.Request) {
myHandler(w,r)
}
Вместо определения новой структуры вы можете определить метод для типа appHandler
:
func (a appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
a(w,r)
}
Теперь вы можете передать appHandler
туда, где требуется appHandler
, а также туда, где требуется Handler
. Если он вызывается как Handler
, метод ServeHTTP
просто переадресует вызов базовой функции.