Go – Methods and Interfaces

Methods

GO has no Classes. However, it has Methods that can be defined on ‘types’. A Method is a function with a special ‘receiver’ argument. In the example below, ‘v‘ is the receiver of the type ‘Square‘, to the method ‘Sqroot‘.

package main

import (
   "math"
   "fmt"
)

type Square struct {
   x, y float64
}

func (v Square) Sqroot() float64 {
   return math.Sqrt(v.x*v.x + v.y*v.y)
}

func main() {
   s := Square{3,4}
   fmt.Println(s.Sqroot())
}
  • Methods can be declared on non-struct types too.
  • A Method can only be declared on a type which is present in the same package as the method.

Pointer Receivers

A method can also be declared with the receiver being a Pointer. A Pointer receiver is very commonly used, as it can modify the underlying value of the type.

There can be two reasons to choose a pointer receiver instead of a value. First is to modify the underlying value and second to avoid copying the value on each method call. If the receiver is large, pointer receiver can prove to be more efficient.

package main

import (
   "math"
   "fmt"
)

type Square struct {
   x, y float64
}

func (v Square) Sqroot() float64 {
   return math.Sqrt(v.x*v.x + v.y*v.y)
}

func (v *Square) Scale(val float64) {
   v.x = v.x * val
   v.y = v.y * val
}

func main() {
   s := Square{3,4}
   s.Scale(100)
   fmt.Println(s.Sqroot())
}

Interfaces

An Interface is a set of method signatures.

type ExInt interface {
	Ifs() float64
}
func(f float64) Ifs() float64 {
   return float64(-f)
}
  • Interfaces are implemented implicitly. No “implements” keyword required.
  • Interfaces can have ‘nil‘ underlying value.
  • An empty interface can hold value of any type interface{}

Errors:

Go uses error values to express error states. An Error type is a built in Interface which looks like this:

type error interface {
    Error() string
}

Functions return an Error value. The calling code should handle errors by testing if the error equals ‘nil

Reader:

  • The reader interface is a part of the ‘io’ package.
  • It helps identify when end of stream of data is reached.
  • The Read method populates the number of bytes of data as specified.
  • The two return values are 1)Number of bytes populated and 2) An error value.
package main

import (
    "fmt"
    "io"
    "strings"
)

func main() {
    r := strings.NewReader("You are using Readers!")

    b := make([]byte, 8)
    for {
        n, err := r.Read(b)
	fmt.Printf("n = %v err = %v b = %v\n", n, err, b)
	fmt.Printf("b[:n] = %q\n", b[:n])
	if err == io.EOF {
	    break
 	    }
        }
}

Output:

n = 8 err =  b = [89 111 117 32 97 114 101 32]
b[:n] = "You are "
n = 8 err =  b = [117 115 105 110 103 32 82 101]
b[:n] = "using Re"
n = 6 err =  b = [97 100 101 114 115 33 82 101]
b[:n] = "aders!"
n = 0 err = EOF b = [97 100 101 114 115 33 82 101]
b[:n] = ""

Previous post: GO – Types (part 2)

Next Post: Go – Concurrency

2 comments

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s