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.