package main
import (
"fmt"
)
func noPointer() string {
return "string"
}
func pointerReturnNil() *string {
return nil // You cannot return nil from a function that returns a string
// but you can return nil from a function that returns a pointer to a string!
// The zero value of a pointer is nil
}
func pointerReturnAndOpt() *string {
s := "string" // &"string" doesn't work.
return &s
}
func main() {
fmt.Println(">>> noPointer() return a string >>> ")
fmt.Println(noPointer()) // prints string
fmt.Println("")
fmt.Println(">>> pointerReturnNil() return nil (*string) >>> ")
fmt.Println(pointerReturnNil()) // prints <nil>
fmt.Println("")
fmt.Println(">>> pointerReturnAndOpt() return &s >>> ")
fmt.Println(pointerReturnAndOpt()) // prints something like 0x40c158 (an address in memory)
fmt.Println("")
fmt.Println(">>> s holds an address im memeory, return &s >>> ")
s := pointerReturnAndOpt() // now s holds an address in memory for a variable
fmt.Println(s) // something like 0x40c138
fmt.Println(*s)
fmt.Println("")
fmt.Println(">>> sp holds the value >>> ")
sp := *s // now sp holds the value found at the address s holds
fmt.Println(sp) // string
fmt.Println(&sp) // sp's address
fmt.Println("")
}
package main
import (
"fmt"
)
type User struct {
Name string
Pet []string
}
func (p2 *User) newPet() {
fmt.Println(*p2, "underlying value of p2 before")
p2.Pet = append(p2.Pet, "Lucy")
fmt.Println(*p2, "underlying value of p2 after")
}
func main() {
u := User{Name: "Anna", Pet: []string{"Bailey"}} // this time we'll generate a pointer!
fmt.Println(u, "u before")
p := &u // Let's make a pointer to u!
p.newPet()
fmt.Println(u, "u after")
// Does Anna have a new pet now? Yes!
}