Hello!
Today’s topic is interfaces. Interfaces are a type that defines a collection of a method’s signature.
Interface
type Printer interface {
Print() string
}
A type will implement the interface when a Print
method is created for it.
type Book struct {
Name string
Author string
}
type Money int
func (b Book) Print() string {
return fmt.Sprintf("%s - %s", b.Author, b.Name)
}
func (m Money) Print() string {
return fmt.Sprintf("You have %d dollars", m)
}
In this code, we have two types Money and Book that implement the Printer
interface because they have a Print
method.
Now how can we use all this? We can create a function that will accept the Printer
type as an argument. And since our Money and Books types implement the Printer
interface, we can pass it as an argument to this function
func WriteLog(p Printer) {
log.Println(p.Print())
}
And now we will call all this the main method
func main() {
a := Book{
Name: "He Who Fights With Monsters",
Author: "Shirtaloon",
}
m := Money(99999999999)
WriteLog(a)
WriteLog(m)
}
And as a result, we will get the following
$ go run main.go
2023/01/15 13:17:01 Shirtaloon - He Who Fights With Monsters
2023/01/15 13:17:01 You have 99999999999 dollars
The complete code will look like this
package main
import (
"fmt"
"log"
)
type Printer interface {
Print() string
}
type Book struct {
Name string
Author string
}
type Money int
func (b Book) Print() string {
return fmt.Sprintf("%s - %s", b.Author, b.Name)
}
func (m Money) Print() string {
return fmt.Sprintf("You have %d dollars", m)
}
func main() {
a := Book{
Name: "He who fight monsters",
Author: "Shirtaloon",
}
m := Money(99999999999)
WriteLog(a)
WriteLog(m)
}
func WriteLog(p Printer) {
log.Println(p.Print())
}
Interfaces can reduce code duplication. They also help with tests, where you can replace the function that connects to the database with special test-only functions that don’t perform the actual connection, but return a result as if the connection had occurred.