|
package main |
|
|
|
import ( |
|
"fmt" |
|
"unsafe" |
|
) |
|
|
|
func main() { |
|
demoString() |
|
demoStruct() |
|
} |
|
|
|
func demoString() { |
|
x := "abc" |
|
pointerToX := &x |
|
copyOfX := x |
|
|
|
fmt.Println("\n> First, we create 3 variables: x (a string), pointerToX (a pointer to x), and copyOfX (a string, copied from x)") |
|
fmt.Printf("X value: %s, held at %p\n", x, &x) |
|
fmt.Printf("pointerToX value (address of the pointer in memory): %p. Value at this address: %s\n", pointerToX, *pointerToX) |
|
fmt.Printf("copyOfX value: %s, held at %p\n", copyOfX, ©OfX) |
|
|
|
// change x |
|
fmt.Println("\n> Now we change the value of x") |
|
x = "abcdef" |
|
fmt.Printf("X value: %s, held at %p\n", x, &x) |
|
fmt.Printf("pointerToX value (address of the pointer in memory): %p. Value at this address: %s\n", pointerToX, *pointerToX) |
|
fmt.Printf("copyOfX value: %s, held at %p\n", copyOfX, ©OfX) |
|
fmt.Printf("> Note that pointerToX points to the new value of '%s', whereas copyOfX made a copy of the value of x, so is still '%s'\n", *pointerToX, copyOfX) |
|
|
|
fmt.Println("\n> How much memory does each value take?") |
|
fmt.Printf("x takes: %d bytes\n", unsafe.Sizeof(x)) |
|
fmt.Printf("pointerToX takes %d bytes\n", unsafe.Sizeof(pointerToX)) |
|
fmt.Printf("copyOfX takes %d bytes\n\n", unsafe.Sizeof(copyOfX)) |
|
} |
|
|
|
type coordinate struct { |
|
x string |
|
y *string |
|
} |
|
|
|
func demoStruct() { |
|
|
|
fmt.Println("\n> How about a struct (z) with a pointer?") |
|
|
|
y := "z_pointer" |
|
z := coordinate{ |
|
x: "z_string", |
|
y: &y, |
|
} |
|
fmt.Printf("z.x value: '%s', held at %p\n", z.x, &z.x) |
|
fmt.Printf("z.y value: '%s', held at %p\n", *z.y, z.y) |
|
|
|
fmt.Printf("z takes: %d bytes\n", unsafe.Sizeof(z)) |
|
fmt.Printf("z.x takes: %d bytes\n", unsafe.Sizeof(z.x)) |
|
fmt.Printf("z.y takes: %d bytes\n", unsafe.Sizeof(z.y)) |
|
|
|
fmt.Println("\n> How about copying a struct with a pointer?") |
|
copyOfZ := z |
|
fmt.Printf("copyOfZ.x is '%s', held at %p\n", copyOfZ.x, ©OfZ.x) |
|
fmt.Printf("copyOfZ.y is '%s', held at %p\n", *copyOfZ.y, copyOfZ.y) |
|
|
|
fmt.Println("\n> What happens the original struct if we change the values in the copied struct?") |
|
y = "copyOfZ_pointer_modified" |
|
copyOfZ.x = "copyOfZ_string_modified" |
|
fmt.Printf("z.x is '%s'\n", z.x) |
|
fmt.Printf("z.y is '%s'\n", *z.y) |
|
fmt.Println("> The string field is unaffected, is it has been copied. However the pointer z.y is now pointing to 'copyOfZ_string_modified'.") |
|
|
|
} |