An interface defines a set of methods. A struct type implements these methods and qualifies the object type as an interface type.

However, how the struct implements the interface?

There are two ways:

  • As a pointer handler
  • As a value handler

Implementation with a struct value handler

package main

import (
	"fmt"
)

type Dummy interface {
  Add(int, int)int
}

type Adder struct {
  magic int
}

func (s Adder) Add(a, b int) int {
  fmt.Printf("magic:%d\n", s.magic)

  s.magic = a + b + s.magic
  return s.magic
}

func GenericAdder(object Dummy) {
    object.Add(2,3)
}

func main() {
  nums := Adder{magic: 43}
  nums.Add(2,3)
  GenericAdder(nums)
}

Output

magic:43
magic:43

Implementation with a pointer handler

package main

import (
	"fmt"
)

type Dummy interface {
  Add(int, int)int
}

type Adder struct {
  magic int
}

func (s *Adder) Add(a, b int) int {
  fmt.Printf("magic:%d\n", s.magic)

  s.magic = a + b + s.magic
  return s.magic
}

func GenericAdder(object Dummy) {
    object.Add(2,3)
}

func main() {
  nums := &Adder{magic: 43}
  nums.Add(2,3)
  GenericAdder(nums)
}

Output

magic:43
magic:48

Conclusion

  • A pointer handler is useful if the struct variable is updated by multiple handlers and the variable state needs to persist.
  • When the method is called with a value of struct, Go uses a copy of the struct variable.
  • The golang function signature stays the same for interface argument. It does not care for the passed argument type (pointer to struct or value of struct)

References

Written with StackEdit.