Interfaces

An interface is a set of methods. We can define an interface by listing out the methods it's expected to support. For example, consider the following interface:

var a interface {
check()
}

Here we are defining a to be a variable that has the type interface{ check() }. What on earth does that mean?

It means that you can put any value into a, as long as the value has a type that has a method called check().

Why is this valuable? It's valuable when considering multiple types that do similar things. Consider the following:

 type complicatedEmail struct {...}

func (e complicatedEmail) check() {...}
func (e complicatedEmail) send(a string) {...}

type simpleEmail string

func (e simpleEmail) check() {...}
func (e simpleEmail) send(a string) {...}

Now we want to write a function do, which does two things:

  • Check that an email address is correct
  • Send "Hello World" to the email

You would need two do functions:

func doC(a complicatedEmail) {
a.check()
a.send("Hello World")
}

func doS(a simpleEmail) {
a.check()
a.send("Hello World")
}

Instead, if that's all the bodies of the functions are, we may opt to do this:

func do(a interface{
check()
send(a string)
}) {
a.check()
a.send("Hello World")
}

This is quite hard to read. So let's give the interface a name:

type checkSender interface{
check()
send(a string)
}

Then we can simply redefine do to be the following:

func do(a checkSender) {
a.check()
a.send("Hello World")
}

A note on naming interfaces in Go. It is customary to name interfaces with a -er suffix. If a type implements check(), then the interface name should be called checker. This encourages the interfaces to be small. An interface should only define a small number of methods—larger interfaces are signs of poor program design.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.163.238