Last active
October 27, 2016 19:36
-
-
Save vcabbage/cb5cdafb1b6f926528cd877d90ea0a89 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"unsafe" | |
) | |
// sliceHeader is the in memory structure of a slice | |
type sliceHeader struct { | |
// Data is the pointer to the underlying array | |
Data uintptr | |
// Len and Cap are the len and cap of the slice | |
Len int | |
Cap int | |
} | |
func main() { | |
// Create a slice of bytes, containing 5 elements | |
x := []byte{1, 2, 3, 4, 5} | |
// Make a copy of x as y | |
y := x | |
// Print out the address and contents of the two slices | |
fmt.Printf("Before mutating x:\n") | |
fmt.Printf("x Address: %p Contents: % x\n", &x, x) | |
fmt.Printf("y Address: %p Contents: % x\n", &y, y) | |
// Pass x to a func that mutates the slice | |
mutate(x) | |
// Print out the address and contents of the two slices after mutating | |
fmt.Printf("\nAfter mutating x:\n") | |
fmt.Printf("x Address: %p Contents: % x\n", &x, x) | |
fmt.Printf("y Address: %p Contents: % x\n", &y, y) | |
// Use unsafe to get a reference to the slice headers | |
xHeader := (*sliceHeader)(unsafe.Pointer(&x)) | |
yHeader := (*sliceHeader)(unsafe.Pointer(&y)) | |
// Print out the contents of the headers | |
fmt.Printf("\nContents of the slice headers:\n") | |
fmt.Printf("x {Data: %#x, Len: %d, Cap: %d}\n", xHeader.Data, xHeader.Len, xHeader.Cap) | |
fmt.Printf("y {Data: %#x, Len: %d, Cap: %d}\n", yHeader.Data, yHeader.Len, yHeader.Cap) | |
// Use unsafe to get a reference to the underlying array | |
array := (*[5]byte)(unsafe.Pointer(xHeader.Data)) | |
// Print out the contents of the array | |
fmt.Printf("\nContents of array the data fields are pointing to:\n") | |
fmt.Printf("array Address: %p Contents: % x\n", array, *array) | |
// Change the array | |
array[2] = 0xff | |
// Print out the address and contents of the two slices after mutating | |
fmt.Printf("\nAfter mutating the underlying array:\n") | |
fmt.Printf("x Address: %p Contents: % x\n", &x, x) | |
fmt.Printf("y Address: %p Contents: % x\n", &y, y) | |
// Attempt to mutate the array in a function | |
mutateArray(*array) | |
// Print out the address and contents of the two slices after mutating | |
fmt.Printf("\nAfter attempting to mutate array in mutateArray():\n") | |
fmt.Printf("x Address: %p Contents: % x\n", &x, x) | |
fmt.Printf("y Address: %p Contents: % x\n", &y, y) | |
} | |
// mutate changes the 3rd element (index 2) of a slice of bytes to 0 | |
func mutate(b []byte) { | |
fmt.Printf("\nAddress of the slice inside mutate()\n") | |
fmt.Printf("b Address: %p\n", &b) | |
b[2] = 0 | |
} | |
// mutateArray changes the 3rd element (index 2) of a 5 element array of bytes to 0xAA | |
func mutateArray(a [5]byte) { | |
fmt.Printf("\nAddress of the array inside mutateArray()\n") | |
fmt.Printf("a Address: %p\n", &a) | |
a[2] = 0xAA | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment