0

In golang, interfaces are extremely important for decoupling and composing code, and thus, an advanced go program might easily define 1000s of interfaces .

How do we evolve these interfaces over time, to ensure that they remain minimal?

  • Are there commonly used go tools which check for unused functions ?

  • Are there best practices for annotating go functions with something similar to java's @Override, which ensures that a declared function is properly implementing a expected contract?

Typically in the java language, it is easy to keep code tightly bound to an interface specification because the advanced tooling allows us to find and remove functions which aren't referenced at all (usually this is highlighted automatically for you in any common IDE).

jayunit100
  • 17,388
  • 22
  • 92
  • 167
  • It may be worth noting that APIs that take in a one-method `interface` could be re-written as taking a function type. See https://stackoverflow.com/a/63557675/12817546. –  Aug 25 '20 at 01:26

2 Answers2

0

Are there commonly used go tools which check for unused functions ?

Sort of, but it is really hard to be sure for exported interfaces. oracle can be used to find references to types or methods, but only if you have all of the code that references you availible on your gopath.

can you ensure a type implements a contract?

If you attempt to use a type as an interface, the compiler will complain if it does not have all of the methods. I generally do this by exporting interfaces but not implementations, and making a constructor:

type MyInterface interface{
    Foo()
}
type impl struct{}
func (i *impl) Foo(){}
func NewImpl() MyInterface{
    return &impl{}
}

This will not compile if impl does not implement all of the required functions.

In go, it is not needed to declare that you implement an interface. This allows you to implement an interface without even referencing the package it is defined in. This is pretty much exactly the opposite of "tightly binding to an interface specification", but it does allow for some interesting usage patterns.

captncraig
  • 22,118
  • 17
  • 108
  • 151
0

What your asking for isn't really a part of Go. There are no best practices for annotating that a function satisfies an interface. I would personally say the only clear best practice is to document which interfaces your types implement so that people can know. If you want to test explicitly (at compile time) if a type implements an interface you can do so using assignment, check out my answer here on the topic; How to check if an object has a particular method?

If you're just looking to take inventory of your code base to do some clean up I would recommend using that assignment method for all your types to generate compile time errors regarding what they don't implement, scale down the declarations until it compiles. In doing so you should become aware of the disparity between what might be implemented and what actually is.

Go is also lacking in IDE options. As a result some of those friendly features like "find all references" aren't there. You can use text searching tricks to get around this, like searching func TheName to get only the declaration and .TheName( to get all invocations. I'm sure you'll get used to it pretty quickly if you continue to use this tooling.

Community
  • 1
  • 1
evanmcdonnal
  • 46,131
  • 16
  • 104
  • 115