Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Start a free Courses trial
to watch this video
One of the most useful things you can do with custom types is define methods for them. A method is a function with a special "receiver" argument. They allow you to define new behaviors for values of a type.
- A method is a function with a special receiver argument: https://golang.org/ref/spec#Method_declarations
- Allows you to define new behaviors for values of a type
- Method declaration looks just like an ordinary function declaration, except it has extra receiver parameter before the function name
- Why "receiver"? Think of calling a method on an object as sending it a message.
- No
this
orself
, just an ordinary parameter name for the receiver
This code defines a type named Title
with a method named FixCase
:
package main
import (
"fmt"
"strings"
)
type Title string
func (t Title) FixCase() string {
return strings.Title(string(t))
}
func main() {
name := Title("the matrix")
fixed := name.FixCase()
fmt.Println(fixed)
}
- The dot notation for calling methods reflects the way that the method is declared.
- Reciever occurs before method name, just like in the declaration
- Compiler looks at type of receiver, then calls method with that name defined on that type
- Don't confuse with package qualifier for exported function names; not the same thing
Here we have some code that uses our Minutes
type again. We've defined an Increment
method that adds 1 to the number of minutes, using the percent sign modulo operator to roll the number over to 0 if it's over 59. This code sample is supposed to print "59", "00", "01" as the number of minutes rolls over to the next hour. But it just prints "58" repeatedly.
package main
import "fmt"
type Minutes int
func (m Minutes) Increment() {
m = (m + 1) % 60
}
func main() {
minutes := Minutes(58)
for i := 1; i <= 3; i++ {
minutes.Increment()
fmt.Println(minutes)
}
}
- This is because
Increment
is modifying a copy of itsMinutes
receiver, and not the original. - As with function parameters, there's no point in a method modifying its receiver parameter; it's a copy
- To allow the
Increment
method to modify its receiver, we need to change the receiver type to a POINTER to aMinutes
value, and then modify the value at that address. Once we do that,Increment
will permanently modify the value each time we call it.
func (m *Minutes) Increment() {
*m = (*m + 1) % 60
}
- Methods with a pointer receiver are more common than methods with a direct value receiver.
- Notice that when we changed the receiver type to take a pointer, we DIDN'T have to change the receiver of the call to
Increment
to&minutes
. (Although we could, and it would still work.) When calling a method with a pointer receiver, Go will automatically convert the receiver to a pointer for us if needed.
// This works, but is non-idiomatic.
(&minutes).Increment()
// Just let it auto-convert.
minutes.Increment()
Go language spec: method declarations
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up