08 - Get to the point
Covered in this module:
- pointers
- dereferencing
pointers
Go defaults to passing parameters by value:
func main() {
star := "Sol"
fmt.Println(star)
toUpper(star)
fmt.Println(star)
}
func toUpper(input string) {
input = strings.ToUpper(input)
}
prints
Sol
Sol
You may have noticed that toUpper didn't have an effect on the output, because it modified its input parameter, which was a copy of the string passed in by main. toUpper would only be able to copy the string initialized in main if we pass by reference, via a pointer.
referencing
You can get the address of a value with the reference syntax:
func main() {
star := "Sol"
fmt.Println(star)
toUpper(&star) // pass reference to star
fmt.Println(star)
}
func toUpper(input *string) {
*input = strings.ToUpper(*input) // modify pointed-to value
}
prints
Sol
SOL
The example above passed a reference to star, which toUpper then dereferences so it can modify the underlying string.
| operator | term | behavior |
|---|---|---|
& |
reference | get the address of the given value |
* |
dereference | get the value from the given address |
Note
* is used to indicate a type as a pointer (e.g. *string) and is also used to dereference pointers.
You can get the address of a value with the reference syntax:
func main() {
moon := "Luna"
fmt.Println(moon)
fmt.Println(&moon)
}
prints
Luna
0xc00000e1e0
Note
Pointer types are referred to verbally by prepending pointer to the type. For example, *string is a pointer string and *int is a pointer int.
nil
Unlike primitives, a pointer can be nil.
func main() {
toUpper(nil)
}
func toUpper(input *string) {
*input = strings.ToUpper(*input)
}
strings.ToUpper is attempting to deference a nil pointer.
It's a good practice to always check nil-able values before trying to use them (unless you know for sure that the pointer can never be nil):
func main() {
toUpper(nil)
}
func toUpper(input *string) {
if input != nil {
*input = strings.ToUpper(*input)
}
}
Hands on!
- In the repo, open the file
./intermediate/08pointers.go - Complete the TODOs
- Run
make 08from project root (alternatively, typego run ./08pointers.go) - Example implementation available on
solutionsbranch