Allocation with new
Go has two allocation primitives, the built-in functions new and make.
new(T): is a built-in function that allocates memory, but it does NOT initialize the memory, it only zeros it.
That is, new(T) allocates zeroed storage for a new item of type T and returns its address, a value of type *T.
In Go terminology, it returns a pointer to a newly allocated zero value of type T.
The zero-value-is-useful property works transitively.
type SyncedBuffer struct {lock sync.Mutexbuffer bytes.Buffer}// Values of type SyncedBuffer are also ready to use// immediately upon allocation or just declaration.p := new(SyncedBuffer) // type *SyncedBuffervar v SyncedBuffer // type SyncedBuffer
Constructors and composite literals
composite literal: is an expression that creates a new instance each time it is evaluated.
func NewFile(fd int, name string) *File {if fd < 0 {return nil}f := File{fd, name, nil, 0}return &f// combine the last two lines//return &File{fd, name, nil, 0}//labele the elements explicitly//return &File{fd: fd, name: name}}
The expressions new(File) and &File{} are equivalent.
create for arrays, slices, and maps
array := [...]string{0: "no error", 1: "Eio", 2: "invalid argument"}slice := []string{10: "no error", 11: "Eio", 12: "invalid argument"}mapping := map[int]string{20: "no error", 21: "Eio", 22: "invalid argument"}
Allocation with make
The built-in function make(T, args) creates slices, maps, and channels ONLY, and it returns an initialized (not zeroed) value of type T (not *T).
v := make([]int, 100)
Arrays
- Arrays are values. Assigning one array to another copies all the elements.
- In particular, if you pass an array to a function, it will receive a copy of the array, not a pointer to it.
- The size of an array is part of its type. The types
[10]intand[20]intare distinct.
Slices
Slices wrap arrays to give a more general, powerful, and convenient interface to sequences of data.
Its run-time data structure holds the pointer, length, and capacity.
Slices hold references to an underlying array, and if you assign one slice to another, both refer to the same array.
slice (here used as a verb) the buffer: slice = slice[0:size]
// signaturefunc (f *File) Read(buf []byte) (n int, err error)// buf[0:32]n, err := f.Read(buf[0:32])
caplenappend
Two-dimensional slices
define an array-of-arrays or slice-of-slices
type Transform [3][3]float64 // A 3x3 array, really an array of arrays.type LinesOfText [][]byte // A slice of byte slices.
two ways to allocate a 2D slice
allocate each slice independently
// Allocate the top-level slice.picture := make([][]uint8, YSize) // One row per unit of y.// Loop over the rows, allocating the slice for each row.for i := range picture {picture[i] = make([]uint8, XSize)}
allocate a single array and point the individual slices into it
// Allocate the top-level slice, the same as before.picture := make([][]uint8, YSize) // One row per unit of y.// Allocate one large slice to hold all the pixels.pixels := make([]uint8, XSize*YSize) // Has type []uint8 even though picture is [][]uint8.// Loop over the rows, slicing each row from the front of the remaining pixels slice.for i := range picture {picture[i], pixels = pixels[:XSize], pixels[XSize:]}
Maps
Maps are built-in data structure that associate values of one type (the key) with values of another type (the element or value).
composite literal syntax
var timeZone = map[string]int{"UTC": 0 * 60 * 60,"EST": -5 * 60 * 60,"CST": -6 * 60 * 60,"MST": -7 * 60 * 60,"PST": -8 * 60 * 60,}offset := timeZone["EST"]// distinguish a missing entry from a zero value, the "comma ok" idiomseconds, ok = timeZone[tz]// blank identifier_, present := timeZone[tz]// use the "comma ok" idiomfunc offset(tz string) int {if seconds, ok := timeZone[tz]; ok {return seconds}log.Println("unknown time zone:", tz)return 0}
A set can be implemented as a map with value type bool.
attended := map[string]bool{"Ann": true,"Joe": true,...}if attended[person] { // will be false if person is not in the mapfmt.Println(person, "was at the meeting")}
to delete a map entry, use the delete built-in functiondelete(timeZone, "PDT")
Printing
formatted printing, in the fmt packagePrintf, Print, PrintlnFprintf, Fprint, FprintlnSprintf, Sprint, Sprintln
os.Stdoutos.Stderr
catchall format %v (for “value”), the result is exactly what Print and Println would produce
printing a struct:%+v: with field names%#v: full Go syntax
quoted string format: %q, ``%#q (backquotes)
hexadecimal string: %x, ``% x
the type of a value: %T
Append
append built-in function
func append(slice []Type, elems ...Type) []Type
You can’t actually write a function in Go where the type Type is determined by the caller.
That’s why append is built in: it needs support from the compiler.
simple example
x := []int{1,2,3}x = append(x, 4, 5, 6)
append a slice to a slice
x := []int{1,2,3}y := []int{4,5,6}x = append(x, y...)
