I want to know what are some of those cases and I have seen some articles too, where we need to return interface rather struct and whether this is a good practice or not ?
Return an interface when you need to. Some examples that come to mind are functions that return behavior in the form of an interface (e.g., io.LimitReader and similar; takes an io.Reader and a length, returns a new io.Reader) and things like factory functions that can return different types that are covered by a common interface.
I think it’s good practice to return an interface when you need to return an interface. If you don’t need to, it’s probably better to return a struct type instead.
I think the receiver end (caller) where it is accepting the return type from a method (be it factory) is satisfying an interface should enforce this and not the implementation end. By returning the interface from another package(for ex), we are doing a coupling between packages.
Sure. But consider something that wants to be able to connect to several different, possibly custom, protocols. Let’s say tcp, tcp+tls://, quic://. We don’t want to hardcode the list of protocols and how to connect them. Instead, we have something that takes a net.Dialer. The actual code doing the dialing ends being something like
getDialer() is already something that returns an interface - the net.Dialer.
But maybe we want a registry or something underlying that getDialer method. Perhaps something as simple as a map[string]net.Dialer would do, but perhaps dialers for the various protocols can’t be reused trivially and we want a factory function for some reason. In that case it would be reasonable for the protocol manager thing to have a func registerProtocol(name string, factory func() net.Dialer) and we would pass it a function that in turn returns a dialer.
Perhaps this whole thing would be exported and called from another package.
Slightly contrived, but there are lots of reasonable times to return interfaces.