Ask HN: Experience with Go Lang Interfaces

2 points by yonisto ↗ HN
I wonder how well go interfaces are working for you in regards to the fact that a type doesn't declare the interface it implements (like in many other languages).

8 years a ago I worked on a 50kloc project and it doesn't seem to matter this way or the other. I didn't find it useful nor did I find it harmful (since then I moved to work in other languages). Then I had the feeling that if the project needed a massive refactor it would really introduce bugs that wouldn't happen elsewhere. But that assumption never got to be tested.

Do you have a battle story regarding go's interfaces? did it save you? did it introduce bugs?

Thanks,

5 comments

[ 0.25 ms ] story [ 25.4 ms ] thread
I got to use interfaces twice in big-ish projects and the biggest advantage I found was decoupling, separation of concerns and code organization.

Go compiler throws an error for circular dependencies and I found that interfaces provided a way to arrange the source code to avoid that error.

It also made testing easier in certain cases because I was able to implement mock interfaces to perform unit tests.

What I found caused quite a few runtime bugs was writing go with a sort of OOP flavor, that is, having most functionality in methods instead of functions. This then forces you to have to pass pointer all over the place and since a null pointer is not something checked during compile time I came across a few panics in go when following that pattern.

Keeping data alone, returning empty structs on errors and having behavior in actions in my case made for a pretty sturdy program that most of the bugs where catch during compile time, and the kind of bugs I came across where mostly external one, i.e. network timeout or dns issues which make for some weird behaviors I hadn’t accounted for

I use Go interfaces fairly often, not least for easy mocking for testing scenarios. Not having to explicitly declare what interface a struct is to implement has never been an issue for me. Modern IDEs provide this information (I prefer JetBrains Goland), so I never feel like I'm working "blind". And if I really feel the need to enforce a certain interface implementation at compile time I can do so:

`var _ InterfaceName = &StructName{}`

Having refactored applications that use interfaces, I've never found the interface usage to make it any more difficult or bug-prone personally. I tend to stick to the "accept interfaces, return structs" guideline, and that's worked pretty well for my use cases.

+1 for goland, allows me to be very productive and with interfaces in particular it makes it very easy to jump from the interface to the implementation(s)
how does it work? there can be endless implementations and the IDE/Compiler doesn't know beforehand what satisfies the interface as oppose to other languages ?