Today while working on my side project I have encountered interesting issue and despite I was able to overcome it I have realised that I might be missing some import concepts about Go. Let me share example code to demostrate the issue I am referring to:
```go package main import ( "net/http" "github.com/gorilla/mux" ) func main() { // We can pass GorillaRouter as Router, because it implement required methods _ = ServerHandler{ router: NewGorillaRouter(), } // We can not pass FailingRouter as Router, because of: // cannot use FailingRouter{} (value of type FailingRouter) as type Router in struct literal: // FailingRouter does not implement Router (wrong type for HandleFunc method) // have HandleFunc(path string, handler func(http.ResponseWriter, *http.Request)) *FailingRoute // want HandleFunc(path string, handler func(http.ResponseWriter, *http.Request)) Route _ = ServerHandler{ router: FailingRouter{}, } } type ServerHandler struct { router Router } type Router interface { HandleFunc(path string, handler func(http.ResponseWriter, *http.Request)) Route } type Route interface { Methods(methods ...string) Route } func NewGorillaRouter() *GorillaRouter { return &GorillaRouter{ router: mux.NewRouter(), } } type GorillaRouter struct { router *mux.Router } func (gr *GorillaRouter) HandleFunc(path string, handler func(http.ResponseWriter, *http.Request)) Route { return &GorillaRoute{ route: gr.router.HandleFunc(path, handler), } } type GorillaRoute struct { route *mux.Route } func (r *GorillaRoute) Methods(methods ...string) Route { r.route = r.route.Methods(methods...) return r } type FailingRouter struct{} func (fr *FailingRouter) HandleFunc(path string, handler func(http.ResponseWriter, *http.Request)) *FailingRoute { return &FailingRoute{} } type FailingRoute struct{} func (r *FailingRoute) Methods(methods ...string) *FailingRoute { return r } ``` For convienence you can find soure code from above and run it here: https://go.dev/play/p/M6N48FeegND Now when code and context is clear question is following: why in `FailingRouter` assignment compiler is not happy while in `GorillaRouter` it is happy? Or to rephrase, why assigning concrete implementation to a parameter of interface type is accepted: ```go type ServerHandler struct { router Router // assigning GorillaRouter to router is accepted } ``` but vice versa is not and throws an error: ```go HandleFunc(path string, handler func(http.ResponseWriter, *http.Request)) *FailingRoute // returning concrete that implements Router is not allowed ``` Is my approach ( `GorillaRouter` ) correct solution for this problem? P.S. Sorry about the title, I am still not sure is it right for this problem description. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/fdc03ca3-f899-455a-8b7c-319c646f483an%40googlegroups.com.