Understanding interface in golang

Ariekusuma
3 min readJun 20, 2024

--

Photo by Vladimir Fedotov on Unsplash
package main
import "fmt"
type Task interface {
Coding(string) bool
Meeting(string) bool
}
type Job struct {
Job string
}
func (j *Job) Coding(data string) bool {
return j.Job == data
}
func (j *Job) Meeting(data string) bool {
return j.Job == data
}
func DoJobs(task Task, data string) {
if task.Coding(data) {
fmt.Println("person doing coding")
}
if task.Meeting(data) {
fmt.Println("person doing meeting")
}
}
func main() {
job := Job{
Job: "coding",
}
DoJobs(&job, "coding")
}

What is an interface

For what i can understand, an interface is a kinda like contract for calling a method.

Just like a required skills inside jobs descriptions.

Let’s say your’e an engineer looking for a job and there is a company that willing to hire an engineer.

The person have set of skills that might be matched with the actual required skill are on that industry.

On the other hand, the company have a list of least skill that you must have beforehand.

So that being said, the company has declare an interface that must be satisfy by the employee in order to get the job.

type Task interface {
Coding(string) bool
Meeting(string) bool
}

As you can see, there was Task interface that declare two function Coding and Meeting. Those two is the required skills for the engineer who applied.

How to use it

1.

The point of using interface is creating a receiver that implementing whats inside the interface.

type Job struct {
Job string
}
func (j *Job) Coding(data string) bool {
return j.Job == data
}
func (j *Job) Meeting(data string) bool {
return j.Job == data
}

So a receiver was a type, and the type is implement whats on the interfaces. So basically what ever Job called, its also implement Coding and Meeting function.

2.

func DoJobs(task Task, data string) {
if task.Coding(data) {
fmt.Println("person doing coding")
}
if task.Meeting(data) {
fmt.Println("person doing meeting")
}
}

The function DoJobs require Task as one of the parameters. Task was an interface that declare Coding and Meeting.

Both Coding and Metting are called inside the DoJobs.

3.

func main() {
job := Job{
Job: "coding",
}
DoJobs(&job, "coding")
}

On the main function, we declare a Job struct and then passed to DoJobs as parameter.

By that means, Job is implementing what ever Task has, which Coding and Meeting.

4.

One thing that can be seen is that if we change the Task interface, we has to sync the implementation on the Job.

type Task interface {
Coding(string) bool
Meeting(string) bool
Pairing(string) bool
}

Let’s say we add one more function on the Task interface as above.

Then it gonna show an error for the Job as the type that implement the interface.

cannot use &job (value of type *Job) as Task value in argument to DoJobs: *Job does not implement Task (missing method Pairing)

By that mean, what ever the Job implementing wasn’t satisfy the required function Task interface has been declared.

5.

But different behaviour shown if we add more implementation on the Job .

type Job struct {
Job string
}
func (j *Job) Coding(data string) bool {
return j.Job == data
}
func (j *Job) Meeting(data string) bool {
return j.Job == data
}
func (j *Job) Debuging(data string) bool {
return j.Job == data
}

If we add more function that use Job as the receiver and its nothing to do with the interface.

That because interface just a list of function that can be used to declare what function available to use.

As long as the Job can satisfy whats inside Task interface the program will be fine.

--

--