Home > database >  Does "Accept Interfaces" break deprecation tooling?
Does "Accept Interfaces" break deprecation tooling?

Time:11-23

Deprecation

The supported way of marking functions as deprecated is something like this:

type MyStruct struct {
}

// MyFunc returns hello
// Deprecated: Use YourFunc
func (m MyStruct) MyFunc() string {
  return "hello"
}

Modern IDEs will highlight any usages of this function and linters might also raise warnings (I haven't personally checked this)

Showing the IDE highlight

Accept interfaces. Return structs.

A popular best practise is "Accept interfaces. Return structs." - which tends to encourage SOLID design in software.

However, the following code - which follows this best practise - conceals the deprecation warning:


// MyInterface specifies a single function that we require from a dependency
type MyInterface interface {
    MyFunc() string
}

func main() {

    var v MyInterface
    v = MyStruct{}
    v.MyFunc()

}

Showing the lack of IDE highlighting

Question

Is there a solution to this problem?

If I were, for example, a library maintainer: how can I ensure that my deprecation warnings are seen by users of the library who are also following best practises and defining their own dependency interfaces.

CodePudding user response:

That seems logical since the method of the interface has not been deprecated. Adding the Deprecated: line to the interface function might help in this case (didn't test, since VSCode doesn't do this yet).

// MyInterface specifies a single function that we require from a dependency
type MyInterface interface {
    // Deprecated: use YourFunc
    MyFunc() string
}

In this case, because the interface only has 1 function you should deprecated the whole thing. Which I know is supported by godoc/pkg.go.dev, take Queryer for example.

// MyInterface specifies a single function that we require from a dependency
// Deprecated: use YourInterface
type MyInterface interface {
    MyFunc() string
}

CodePudding user response:

Add the deprecation comment on the interface method.

// MyInterface specifies a single function that we require from a dependency
type MyInterface interface {
    // Deprecated: Use YourFunc
    MyFunc() string
}

In GoLand the method appears as (no code formatting to show strikethrough):

var v MyInterface
v = MyStruct{}
v.MyFunc()

This maybe is not ideal because it shows the warning for all interface implementations, not just MyStruct.

Let's say you have two structs implementing the interface, MyStruct and YourStruct and only MyStruct.MyFunc is deprecated, I bet you don't want to show the deprecation warning when the value is YourStruct: that one is not deprecated.

The point is that the deprecation warning appears only on MyStruct.MyFunc because it is relevant only to that usage. It is not relevant to all possible implementors of MyInterface.

If you unbox it v.(MyStruct).MyFunc() it will show the deprecation warning.

  • Related