2

In Go, you don’t state that you need to implement an interface, you just do it (it’s called ‘structural typing’ similar to ‘duck typing’ in dynamic languages). What if you want to force a type to implement an interface (like when you ‘inherit’ an interface in C# or Java for instance)? In other words, what if forgetting to implement an interface (or getting the signature wrong) is a mistake and you want to catch that mistake early. What is the best way to do it?

Franck Jeannin
  • 6,107
  • 3
  • 21
  • 33
  • 1
    Write an test where you use the type as the required interface. The test wouldn't pass unless the type implements the said interface. – ain Dec 26 '16 at 09:50
  • Does this answer your question? [Ensure a type implements an interface at compile time in Go](https://stackoverflow.com/a/60663003) –  Mar 13 '20 at 03:49

2 Answers2

4

Best thing you may do is try to assign an instance of the type to a interface variable

For example you want to make sure type A implements Stringer interface.

You may do like this

var _ Stringer = new(A) //or
var _ Stringer = A{}

Here is the sample program, In the example A implements the interface and B does not

package main

import (
    "fmt"
)

type Stringer interface {
   String() string
}

type A struct {
}

func (a A) String() string {
    return "A"
}

type B struct {}


var _ Stringer = new(A)
var _ Stringer = new(B)

func main() {

    fmt.Println("Hello, playground")
}

Play link here : play.golang

  • 1
    Thanks @Sarathsp for that elegant solution. I have learned that it’s sometimes called a canary test (from the poor canary in the mine that would die from gas poisoning quickly enough to warn the mines). – Franck Jeannin Dec 26 '16 at 09:56
  • I assume that the dummy variable will just be discarded by the compiler and consume neither space nor CPU time. I guess, it can always be moved to a _test.go file if in doubt. – Franck Jeannin Dec 26 '16 at 10:04
  • This will be discarded by the compiler . Moving that to test file is your call , but i would suggest put it there as it makes the implemenation requirement explicit :D, BTW , you my try `var _ Stringer = (*A)(nil)` if memory is a concern :D – Sarath Sadasivan Pillai Dec 26 '16 at 10:10
0

To complete what @Sarathsp said: Basically, by declaring a dummy variable (underscore means that it is not used) of the interface type while assigning an instance of your type to it, you get very explicit compile-time errors:

    type MyType struct {
    }

    func (*MyType) Read() {

    }

    var _ io.Reader = &MyType{}


cannot use MyType literal (type *MyType) as type io.Reader in assignment:
        *MyType does not implement io.Reader (missing Read method)

Or

cannot use MyType literal (type *MyType) as type io.Reader in assignment:
        *MyType does not implement io.Reader (wrong type for Read method)
                have Read()
                want Read([]byte) (int, error)
Franck Jeannin
  • 6,107
  • 3
  • 21
  • 33