The following is a standard code to check at compile time if struct A implements interface fooer
var _ myInterface = (*myStruct)(nil)
It is for example presented here.
I am a little confused of cases when A and when *A implements a given interface. I think the above code fails to differentiate between those two cases. This may cause some hard-to-find bugs (e.g. json.Marshaler interface)
package main
type fooer interface{ foo() }
type A struct{}
type B struct{}
func (*A) foo() {}
func (B) foo() {}
var _ fooer = (*A)(nil)
var _ fooer = *(*A)(nil) // fails to compile
var _ fooer = A{} // fails to compile
var _ fooer = &A{}
var _ fooer = (*B)(nil)
var _ fooer = *(*B)(nil)
var _ fooer = B{}
var _ fooer = &B{}
func main() {}
Sadly maybe, I did not manage to make compilation fails for struct B, where foo is defined on non-pointer receiver. Is it an issue in practice? Is there a way to test that? Would it be better practice to use var _ myInterface = myStruct{} to test if a type implements an interface?