Summary: in this tutorial, you will learn how to use the Go interface to write functions that accept different types that implement the same interface.
In Go, an interface is a type that specifies a set of method signatures. This means that the methods you specify in the interfaces do not have implementations.
Defining an interface
Here’s the syntax for defining an interface in Go:
type InterfaceName interface {
method1(parameters) returnType1
method2(parameters) returnType2
...
}
Code language: Go (go)
In this syntax:
- First, specify the type, interface name, and the
interface
keyword. - Second, list one or more methods within the curly braces.
For example, the following defines an interface named Shape
:
type Shape interface {
Area() float64
Perimeter() float64
}
Code language: Go (go)
The Shape
interface has two methods Area()
and Perimeter()
that accepts no parameters and returns a float64
value.
Implementing an interface
To implement an interface, you provide the type with implementations of the methods defined in the interface.
For example, the following defines the Rectangle
struct type that implements the Shape
interface:
type Rectangle struct {
Width, Length float64
}
func (r Rectangle) Area() float64 {
return r.Width * r.Length
}
func (r Rectangle) Perimeter() float64 {
return 2 * (r.Width + r.Length)
}
Code language: Go (go)
Since the Rectangle
struct implements the Shape
interface, you can use it anywhere that accepts the Shape
interface type.
Using the interface
The following defines a function that accepts a slice of Shape
interfaces:
func calculateTotalArea(shapes []Shape) float64 {
var totalArea float64
for _, s := range shapes {
totalArea += s.Area()
}
return totalArea
}
Code language: Go (go)
Since the Rectangle
implements the Shape
interface, you can pass it to the calculateTotalArea
function:
package main
import "fmt"
type Shape interface {
Area() float64
Perimeter() float64
}
type Rectangle struct {
Width, Length float64
}
func (r Rectangle) Area() float64 {
return r.Width * r.Length
}
func (r Rectangle) Perimeter() float64 {
return 2 * (r.Width + r.Length)
}
func calculateTotalArea(shapes []Shape) float64 {
var totalArea float64
for _, s := range shapes {
totalArea += s.Area()
}
return totalArea
}
func main() {
shapes := []Shape{
Rectangle{Width: 5, Length: 10},
Rectangle{Width: 3, Length: 5},
}
fmt.Printf("Total area: %.2f\n", calculateTotalArea(shapes))
}
Code language: Go (go)
Output:
Total area: 65.00
Code language: Go (go)
Adding more types that implement the same interface
The following defines the Circle
struct type that implements the Shape
interface:
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return math.Pi * c.Radius * c.Radius
}
func (c Circle) Perimeter() float64 {
return 2 * math.Pi * c.Radius
}
Code language: Go (go)
Since Circle
implements the Shape
interface, it is a Shape
. We can also use the Circle
as a Shape
. For example:
func main() {
shapes := []Shape{
Rectangle{Width: 5, Length: 10},
Rectangle{Width: 3, Length: 5},
Circle{Radius: 10},
}
fmt.Printf("Total area: %.2f\n", calculateTotalArea(shapes))
}
Code language: Go (go)
Output:
Total area: 379.16
Code language: Go (go)
Here’s the complete program:
package main
import (
"fmt"
"math"
)
type Shape interface {
Area() float64
Perimeter() float64
}
type Rectangle struct {
Width, Length float64
}
func (r Rectangle) Area() float64 {
return r.Width * r.Length
}
func (r Rectangle) Perimeter() float64 {
return 2 * (r.Width + r.Length)
}
func calculateTotalArea(shapes []Shape) float64 {
var totalArea float64
for _, s := range shapes {
totalArea += s.Area()
}
return totalArea
}
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 {
return math.Pi * c.Radius * c.Radius
}
func (c Circle) Perimeter() float64 {
return 2 * math.Pi * c.Radius
}
func main() {
shapes := []Shape{
Rectangle{Width: 5, Length: 10},
Rectangle{Width: 3, Length: 5},
Circle{Radius: 10},
}
fmt.Printf("Total area: %.2f\n", calculateTotalArea(shapes))
}
Code language: Go (go)
Interfaces allow you to write functions that accept different types as long as they implement the same interface.
Summary
- An interface is a type that includes a set of method signatures.
- To implement an interface, define methods specified in the interface for the type.
- An interface allows you to write code that accepts different types as long as they have the same interface.