The linked article doesn't elaborate on the "return structs" part. Personally I prefer to return only the bare minimal functionality that your caller should expect, so that they don't depend on something they shouldn't and you don't break them when you change to give them less. What are the best reasons to return structs?
This is also the style advocated by the standard library. See for example the helper functions for io.Reader: https://golang.org/pkg/io/#Reader
For example, `io.TeeReader` returns `io.Reader` (the interface). The underlying type that implements the tee functionality is left private because you don't need to be able to see it. It really drives home the point that the return value is "just another io.Reader".
This depends on the purpose of your function. It is the responsibility of the caller to not assume too much about dependencies, but you should help by being clear about the expected types of your functions. However that doesn't mean you should restrict yourself to always returning interfaces.
Imagine your documentation says: this functions returns a List of items. You can still returns a CopyOnWriteArrayList. Your only promise is that it will satisfy List, but if you returned the interface, you would remove the ability for the next developer, which has more information than you, to rely on it. Since you cannot know in advance who is going to use the return value, giving the most specific type is the approach that is the most composable. A private function that knows what to do with CopyOnWriteArrayList can rely on it. Other code that works on List can accept the value because it is a List.
If your interface is going to be public, then relying on the documentation might not be enough, and then you are welcome to define facade functions which hide internals.
>Imagine your documentation says: this functions returns a List of items. You can still returns a CopyOnWriteArrayList.
I don't write in Go so I don't know how the Go community feels about this, but I don't like the idea of a mismatch between documentation and implementation. A non-trivial number of people will only read the documentation when something goes wrong. If the function is defined as returning a CopyOnWriteArrayList they will assume that's the return type. If they bother to read the documentation, the mismatch will be confusing and the more obvious inference will be that the documentation is simply out of date.
>you would remove the ability for the next developer, which has more information than you, to rely on it
Yes, this is exactly what I _want_ to do. If the fact that I produce a specialised type rather than an interface is purely incidental, then I don't _want_ people to rely on it -- I won't be able to change my mind later. "Don't promise what you can't deliver." If it's not incidental, then of course be as precise as you feel is appropriate.
Also I'll concede that this opinion is mostly for library writing, less so for internal usage where the caller is you/your team anyway.