Structural typing vs Class-based interface
In other OOP languages, the interface is a contract by implementing class. By Contrast, Golang checks the interface implementation for struct when you call struct with interface, not by implementing struct.
Let's see some code
C#
interface IMessageService{ void Send() } // compile time error to show the class doesn't implement the interface public class MyService: IMessageService{ }
Go
func main() { // compile time error happens when using it var service IMessageService = &MyService{} service.Send() } type IMessageService interface { Send() } type MyService struct { }
Can we check the interface implementation before calling it?
Of course, we can. There're 2 options to do this.
- Constructor returns interface:
func NewMyMessageService() IMessageService { return &MyService{} }
- Using underscore to do check
var _ IMessageService = &MyService{}
In case you have multiple interfaces to implement:
- Embedding multiple interfaces into one, and return it
type IMyService interface { IMessageService IEmailService } type IMessageService interface { Send() } type IEmailService interface { SendEmail() } type MyService struct { } func NewMyService() *IMyService { return &MyService{} }
Or
- Using underscore to do multiple checks
var _ IMessageService = &MyService{} var _ IEmailService = &MyService{}
Underscore is more useful
"_" is also useful to check whether the 3rd party struct has implement client side interface.
import( "thirdparty" ) var _ IMessageService = &thirdparty.NotMyService{}
Top comments (0)