package
0.0.0-20200526015148-b343531734ec
Repository: https://github.com/fakorede/learning-golang.git
Documentation: pkg.go.dev

# Packages

No description provided by the author

# README

Method Declaration

Methods makes it easier to encapsulate fields within an object and control how state is modified. Methods are shorter and have more succint naming convention.

In Go, we can define a method on a struct and choose if the receiver (the object which the method is executed on) is of type Value or a Pointer.

We define a type struct named SemanticVersion

type SemanticVersion struct {
	major, minor, patch int
}

We then define a function NewSemanticVersion which takes 3 parameters of type int and then returns a type of SemanticVersion.

func NewSemanticVersion(major, minor, patch int) SemanticVersion {
	return SemanticVersion{
		major: major,
		minor: minor,
		patch: patch,
	}
}

Value Receiver

We can now define a method on this struct which we call String. This method takes a receiver(object which we call this method on) which finally returns a string.

func (sv SemanticVersion) String() string {
	return fmt.Sprintf("%d.%d.%d", sv.major, sv.minor, sv.patch)
}

The receiver used here is a Value Receiver. The Value Receiver makes a copy of the type and passes it to the method. The method stack now holds an equal object but at a different location on memory.

Pointer Receiver

Lets imagine we need to make changes to the versions in this object. We need to define new new methods

// IncrementMajor : this method increments and prints the major version
func (sv SemanticVersion) IncrementMajor() {
	sv.major++
}

Now, if when we call this method, we observe no change at all

func main() {
	sv := simplemath.NewSemanticVersion(1, 2, 3)
	sv.IncrementMajor()
	fmt.Println(sv.String())
}
go run main.go
1.2.3

This is because the Value Receiver passes different copies of the sv object to each method.

To get the desired behavior here, we need to use a Pointer based method receiver. The Pointer Receiver passes the address of a type to the method. The method stack now has a reference to the original object.

// IncrementMajor : this method increments and prints the major version
func (sv *SemanticVersion) IncrementMajor() {
	sv.major++
}

Now, when we run the program again, we get the desired output like so:

go run main.go
2.2.3

Conclusion

In Go, it is idiomatic to set all of our methods to pointer-based receivers.

Pointer Receivers are very useful when modifying state within a type.

It is also very useful when we have a huge type and we do not want to be copying all over the place.