loading...

Brief Introduction to Interfaces in Go

shearywtan profile image Sheary Tan ・3 min read

As a new Gopher and a CodeNewbie who has never typed C++ or any strongly-typed languages before, I was having a hard time looking for some beginners-friendly resources about Interfaces in Go.

So here I am, decided to write one and doing my best to help any beginners.


What is Interfaces?

Interfaces in Go provide a way to specify the behavior of an object: if something can do this, then it can be used here. - Effective Go

Well it basically means interfaces is a type that has a bunch of methods.

Alright without talking too much, lets make things clear today.

Write some code

Aim: To implement two methods sum() and substr() which will then print out the sum and subtraction of two numbers.

1) Let's start with the setup

package main

import "fmt"

func main() {
}

2) Then the type, here we have item1 and item2 with two numbers type float64 respectively:

package main

import "fmt"
type item1 struct {
    num1, num2 float64
}

type item2 struct {
    num1, num2 float64
}

func main() {
}

3) Now we need some instructions (methods) for the code to work:

package main

import "fmt"

type item1 struct {
    num1, num2 float64
}

type item2 struct {
    num1, num2 float64
}
// Method
func (a item1) sum() float64 {
    return a.num1 + a.num2
}

// Method
func (a item1) substr() float64 {
    return a.num1 - a.num2
}

// Method
func (b item2) sum() float64 {
    return b.num1 + b.num2
}

// Method
func (b item2) substr() float64 {
    return b.num1 - b.num2
}
func main() {
}

Before continuing, let's get a better understanding on the method.

// Method
func (b item2) substr() float64 {
    return b.num1 - b.num2
}

b is a reference to item2, which is the way we access num1 and num2 inside item2. Then we have the name substr(), the return type float64 and the return method.

4) Implementing result1 and result2 and print out the result:

package main

import "fmt"

type item1 struct {
    num1, num2 float64
}

type item2 struct {
    num1, num2 float64
}

// Method
func (a item1) sum() float64 {
    return a.num1 + a.num2
}

// Method
func (a item1) substr() float64 {
    return a.num1 - a.num2
}

// Method
func (b item2) sum() float64 {
    return b.num1 + b.num2
}

// Method
func (b item2) substr() float64 {
    return b.num1 - b.num2
}
// Result 1 & Result 2
func result1(i item1) {
    fmt.Println("Sum: ", i.sum())
    fmt.Println("Substr: ", i.substr())
}

func result2(i item2) {
    fmt.Println("Sum: ", i.sum())
    fmt.Println("Substr: ", i.substr())
}

func main() {
    a := item1{num1: 10, num2: 5}
    b := item2{num1: 20, num2: 10}

    result1(a) 
    result2(b)
}

// Sum:  15
// Substr:  5
// Sum:  30
// Substr:  10

Here we passed two variables: a and b to two functions: result1 and result2, and got the results.

But here is the problem:

Why do we need to write two functions (result1 and result2) that basically do the same thing?


So here is the thing you have been waiting for: Interfaces

5) Implementing interface. I mentioned before, interface is a type that has a collection of methods (function). It has both sum() and substr(), which are the names of the methods below:

package main

import "fmt"
type math interface {
    sum() float64
    substr() float64
}
type item1 struct {
    num1, num2 float64
}

type item2 struct {
    num1, num2 float64
}

// Method
func (a item1) sum() float64 {
    return a.num1 + a.num2
}

// Method
func (a item1) substr() float64 {
    return a.num1 - a.num2
}

// Method
func (b item2) sum() float64 {
    return b.num1 + b.num2
}

// Method
func (b item2) substr() float64 {
    return b.num1 - b.num2
}

func main() {

}

6) Print out the result:

package main

import "fmt"

type math interface {
    sum() float64
    substr() float64
}

type item1 struct {
    num1, num2 float64
}

type item2 struct {
    num1, num2 float64
}

// Method
func (a item1) sum() float64 {
    return a.num1 + a.num2
}

// Method
func (a item1) substr() float64 {
    return a.num1 - a.num2
}

// Method
func (b item2) sum() float64 {
    return b.num1 + b.num2
}

// Method
func (b item2) substr() float64 {
    return b.num1 - b.num2
}
func result(m math) {
    fmt.Println("Sum: ", m.sum())
    fmt.Println("Substr: ", m.substr())
}

func main() {
    a := item1{num1: 10, num2: 5}
    b := item2{num1: 20, num2: 10}

    result(a)
    result(b)
}

// Sum:  15
// Substr:  5
// Sum:  30
// Substr:  10

So now we just have to include interface math with result, we will then be able to access sum() and substr() by calling it once in the main() section.
Here we are calling result once for both variables and got the same results!

Continue -> Empty interface

Thanks for reading my first ever published article!

Discussion

pic
Editor guide
Collapse
tomxlawson profile image
tomxlawson

This is a clear example of the use of an interface. But, wouldn't it be easier just to replace these lines:

result(a) and result(b)

With these lines?

fmt.Println("Sum: ", a.sum(), "Substr: ", a.substr()) // Sum: 15 Substr: 5
fmt.Println("Sum: ", b.sum(), "Substr: ", b.substr()) // Sum: 30 Substr: 10

Then remove the "math" interface and the "result" function. This would result in less code for this example. But I guess interfaces are still useful if the code is more complex in this.