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)