Methods in Go Programming

Welcome to part 7 of the Go programming tutorial series. We've been talking about structs, and we saw how to create a struct in the previous tutorial, along with accessing values from the struct. Now, we're curious about how methods might work. While Go doesn't have classes, it does have methods. The methods are not defined within the struct, however. Instead, they're associated with the struct. Here, you can either let these methods just access data via working as a copy of the struct, or you can actually point through and modify the object. Methods that just access values are called value receivers and methods that can modify information are pointer receivers.

Our starting code, from the previous tutorial:

package main

import "fmt"

type car struct {
	gas_pedal uint16     //min: 0,      max: 65535    16bit
	brake_pedal uint16   //min: 0,      max: 65535
	steering_wheel int16 //min: -32768  max: 32768
	top_speed_kmh float64 //what's our top speed?

func main() {
	//a_car := car{gas_pedal: 16535, brake_pedal: 0, steering_wheel: 12562, top_speed_kmh: 225.0}
	a_car := car{22314,0,12562,225.0}
	fmt.Println("gas_pedal:",a_car.gas_pedal, "brake_pedal:",a_car.brake_pedal,"steering_wheel:",a_car.steering_wheel)

Add the following two constants:

const usixteenbitmax float64 = 65535
const kmh_multiple float64 = 1.60934

We will be using these for calculating speed. The first is just the max value for an uninsigned 16bit integer that is our gas pedal "sensor" (mimicking something like the trigger on an xbox360 controller), the second is the multiple that can be used to get MPH from KMH or visa versa.

At this point, we can access values from a_car, but what about with running methods? Continuing with our example of using a car, let's say we wanted to convert the gas_pedal value to some sort of actual speed, so our goal would be to be able to do something like a_car.kmh() or a_car.mph().

In order to do this, we don't need to actually modify the a_car variable, so we can use a method on a value, called a value receiver:

func (c car) kmh() float64 {
	return float64(c.gas_pedal) * (c.top_speed_kmh/usixteenbitmax)

Here, between the func keyword and the name of the function, we pass the variable and type. We use c, short for car, and then car, which is in association with the car struct. In this case, the method gets a copy of the object, so you cannot actually modify it here, you can only take actions or do something like coming up with a calculation like we're doing here.

Similarly, we can do the mph method:

func (c car) mph() float64 {
	return float64(c.gas_pedal) * (c.top_speed_kmh/kmh_multiple/usixteenbitmax)

Now, what if instead of just accessing, and making calculations on, values isn't enough? What if we want to instead modify these values? To do this, we'll need to use a pointer receiver, which we'll cover in the next tutorial.

The next tutorial:

  • Introduction to the Go Programming Language
  • Go Language Syntax
  • Go Language Types
  • Pointers in Go Programming
  • Simple Web App in Go Programming
  • Structs in the Go Programming Language
  • Methods in Go Programming
  • Pointer Receivers in Go Programming
  • More Web Dev in Go Language
  • Acessing the Internet in Go
  • Parsing XML with Go Programming
  • Looping in Go Programming
  • Continuing our Go Web application
  • Mapping in Golang
  • Mapping Golang sitemap data
  • Golang Web App HTML Templating
  • Applying templating to our Golang web app
  • Goroutines - Concurrency in Goprogramming
  • Synchronizing Goroutines - Concurrency in Golang
  • Defer - Golang
  • Panic and Recover in Go Programming
  • Go Channels - Concurrency in Go
  • Go Channels buffering, iteration, and synchronization
  • Adding Concurrency to speed up our Golang Web Application