From 94439492077c16876c1243221923f51cb237627c Mon Sep 17 00:00:00 2001 From: Andrew Gerrand Date: Fri, 6 Jan 2012 09:21:43 +1100 Subject: [PATCH] doc: add Slices: usage and internals article Originally published on the Go blog on 5 Jan 2011: http://blog.golang.org/2011/01/go-slices-usage-and-internals.html R=golang-dev, gri CC=golang-dev https://golang.org/cl/5516046 --- doc/Makefile | 1 + doc/articles/slice-1.png | Bin 0 -> 6334 bytes doc/articles/slice-2.png | Bin 0 -> 7220 bytes doc/articles/slice-3.png | Bin 0 -> 7303 bytes doc/articles/slice-array.png | Bin 0 -> 1237 bytes doc/articles/slice-struct.png | Bin 0 -> 3650 bytes doc/articles/slices_usage_and_internals.html | 477 +++++++++++++++++++ doc/articles/slices_usage_and_internals.tmpl | 436 +++++++++++++++++ doc/progs/run | 1 + doc/progs/slices.go | 55 +++ 10 files changed, 970 insertions(+) create mode 100644 doc/articles/slice-1.png create mode 100644 doc/articles/slice-2.png create mode 100644 doc/articles/slice-3.png create mode 100644 doc/articles/slice-array.png create mode 100644 doc/articles/slice-struct.png create mode 100644 doc/articles/slices_usage_and_internals.html create mode 100644 doc/articles/slices_usage_and_internals.tmpl create mode 100644 doc/progs/slices.go diff --git a/doc/Makefile b/doc/Makefile index daa0a5ea2b6..9a52b257a36 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -11,6 +11,7 @@ GOFILES=\ HTML=\ articles/defer_panic_recover.html\ articles/error_handling.html\ + articles/slices_usage_and_internals.html\ effective_go.html\ go1.html\ go_tutorial.html\ diff --git a/doc/articles/slice-1.png b/doc/articles/slice-1.png new file mode 100644 index 0000000000000000000000000000000000000000..ba465cf71849e590ecc4e614f423f7cc97d0d1b0 GIT binary patch literal 6334 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 literal 0 HcmV?d00001 diff --git a/doc/articles/slice-2.png b/doc/articles/slice-2.png new file mode 100644 index 0000000000000000000000000000000000000000..a57581e8cfcf706f8206d1d1069d976b7166816d GIT binary patch literal 7220 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 C@0>UQ literal 0 HcmV?d00001 diff --git a/doc/articles/slice-3.png b/doc/articles/slice-3.png new file mode 100644 index 0000000000000000000000000000000000000000..64ece5e877dff6d486a7c97333909c403f34a7d4 GIT binary patch literal 7303 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 literal 0 HcmV?d00001 diff --git a/doc/articles/slice-struct.png b/doc/articles/slice-struct.png new file mode 100644 index 0000000000000000000000000000000000000000..f9141fc5920ab001dbdfd66bd338e8829d411917 GIT binary patch literal 3650 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 + + + +

+Go's slice type provides a convenient and efficient means of working with +sequences of typed data. Slices are analogous to arrays in other languages, but +have some unusual properties. This article will look at what slices are and how +they are used. +

+ +

+Arrays +

+ +

+The slice type is an abstraction built on top of Go's array type, and so to +understand slices we must first understand arrays. +

+ +

+An array type definition specifies a length and an element type. For example, +the type [4]int represents an array of four integers. An array's +size is fixed; its length is part of its type ([4]int and +[5]int are distinct, incompatible types). Arrays can be indexed in +the usual way, so the expression s[n] accesses the nth +element: +

+ +
+var a [4]int
+a[0] = 1
+i := a[0]
+// i == 1
+
+ +

+Arrays do not need to be initialized explicitly; the zero value of an array is +a ready-to-use array whose elements are themselves zeroed: +

+ +
+// a[2] == 0, the zero value of the int type
+
+ +

+The in-memory representation of [4]int is just four integer values laid out sequentially: +

+ +

+ +

+ +

+Go's arrays are values. An array variable denotes the entire array; it is not a +pointer to the first array element (as would be the case in C). This means +that when you assign or pass around an array value you will make a copy of its +contents. (To avoid the copy you could pass a pointer to the array, but +then that's a pointer to an array, not an array.) One way to think about arrays +is as a sort of struct but with indexed rather than named fields: a fixed-size +composite value. +

+ +

+An array literal can be specified like so: +

+ +
+b := [2]string{"Penn", "Teller"}
+
+ +

+Or, you can have the compiler count the array elements for you: +

+ +
+b := [...]string{"Penn", "Teller"}
+
+ +

+In both cases, the type of b is [2]string. +

+ +

+Slices +

+ +

+Arrays have their place, but they're a bit inflexible, so you don't see them +too often in Go code. Slices, though, are everywhere. They build on arrays to +provide great power and convenience. +

+ +

+The type specification for a slice is []T, where T is +the type of the elements of the slice. Unlike an array type, a slice type has +no specified length. +

+ +

+A slice literal is declared just like an array literal, except you leave out +the element count: +

+ +
+letters := []string{"a", "b", "c", "d"}
+
+ +

+A slice can be created with the built-in function called make, +which has the signature, +

+ +
+func make([]T, len, cap) []T
+
+ +

+where T stands for the element type of the slice to be created. The +make function takes a type, a length, and an optional capacity. +When called, make allocates an array and returns a slice that +refers to that array. +

+ +
+var s []byte
+s = make([]byte, 5, 5)
+// s == []byte{0, 0, 0, 0, 0}
+
+ +

+When the capacity argument is omitted, it defaults to the specified length. +Here's a more succinct version of the same code: +

+ +
+s := make([]byte, 5)
+
+ +

+The length and capacity of a slice can be inspected using the built-in +len and cap functions. +

+ +
+len(s) == 5
+cap(s) == 5
+
+ +

+The next two sections discuss the relationship between length and capacity. +

+ +

+The zero value of a slice is nil. The len and +cap functions will both return 0 for a nil slice. +

+ +

+A slice can also be formed by "slicing" an existing slice or array. Slicing is +done by specifying a half-open range with two indices separated by a colon. For +example, the expression b[1:4] creates a slice including elements +1 through 3 of b (the indices of the resulting slice will be 0 +through 2). +

+ +
+b := []byte{'g', 'o', 'l', 'a', 'n', 'g'}
+// b[1:4] == []byte{'o', 'l', 'a'}, sharing the same storage as b
+
+ +

+The start and end indices of a slice expression are optional; they default to zero and the slice's length respectively: +

+ +
+// b[:2] == []byte{'g', 'o'}
+// b[2:] == []byte{'l', 'a', 'n', 'g'}
+// b[:] == b
+
+ +

+This is also the syntax to create a slice given an array: +

+ +
+x := [3]string{"Лайка", "Белка", "Стрелка"}
+s := x[:] // a slice referencing the storage of x
+
+ +

+Slice internals +

+ +

+A slice is a descriptor of an array segment. It consists of a pointer to the +array, the length of the segment, and its capacity (the maximum length of the +segment). +

+ +

+ +

+ +

+Our variable s, created earlier by make([]byte, 5), +is structured like this: +

+ +

+ +

+ +

+The length is the number of elements referred to by the slice. The capacity is +the number of elements in the underlying array (beginning at the element +referred to by the slice pointer). The distinction between length and capacity +will be made clear as we walk through the next few examples. +

+ +

+As we slice s, observe the changes in the slice data structure and +their relation to the underlying array: +

+ +
+s = s[2:4]
+
+ +

+ +

+ +

+Slicing does not copy the slice's data. It creates a new slice value that +points to the original array. This makes slice operations as efficient as +manipulating array indices. Therefore, modifying the elements (not the +slice itself) of a re-slice modifies the elements of the original slice: +

+ +
+d := []byte{'r', 'o', 'a', 'd'}
+e := d[2:] 
+// e == []byte{'a', 'd'}
+e[1] == 'm'
+// e == []byte{'a', 'm'}
+// d == []byte{'r', 'o', 'a', 'm'}
+
+ +

+Earlier we sliced s to a length shorter than its capacity. We can +grow s to its capacity by slicing it again: +

+ +
+s = s[:cap(s)]
+
+ +

+ +

+ +

+A slice cannot be grown beyond its capacity. Attempting to do so will cause a +runtime panic, just as when indexing outside the bounds of a slice or array. +Similarly, slices cannot be re-sliced below zero to access earlier elements in +the array. +

+ +

+Growing slices (the copy and append functions) +

+ +

+To increase the capacity of a slice one must create a new, larger slice and +copy the contents of the original slice into it. This technique is how dynamic +array implementations from other languages work behind the scenes. The next +example doubles the capacity of s by making a new slice, +t, copying the contents of s into t, and +then assigning the slice value t to s: +

+ +
+t := make([]byte, len(s), (cap(s)+1)*2) // +1 in case cap(s) == 0
+for i := range s {
+        t[i] = s[i]
+}
+s = t
+
+ +

+The looping piece of this common operation is made easier by the built-in copy +function. As the name suggests, copy copies data from a source slice to a +destination slice. It returns the number of elements copied. +

+ +
+func copy(dst, src []T) int
+
+ +

+The copy function supports copying between slices of different +lengths (it will copy only up to the smaller number of elements). In addition, +copy can handle source and destination slices that share the same +underlying array, handling overlapping slices correctly. +

+ +

+Using copy, we can simplify the code snippet above: +

+ +
+t := make([]byte, len(s), (cap(s)+1)*2)
+copy(t, s)
+s = t
+
+ +

+A common operation is to append data to the end of a slice. This function +appends byte elements to a slice of bytes, growing the slice if necessary, and +returns the updated slice value: +

+ +
func AppendByte(slice []byte, data ...byte) []byte {
+    m := len(slice)
+    n := m + len(data)
+    if n > cap(slice) { // if necessary, reallocate
+        // allocate double what's needed, for future growth.
+        newSlice := make([]byte, (n+1)*2)
+        copy(newSlice, slice)
+        slice = newSlice
+    }
+    slice = slice[0:n]
+    copy(slice[m:n], data)
+    return slice
+}
+ +

+One could use AppendByte like this: +

+ +
+p := []byte{2, 3, 5}
+p = AppendByte(p, 7, 11, 13)
+// p == []byte{2, 3, 5, 7, 11, 13}
+
+ +

+Functions like AppendByte are useful because they offer complete +control over the way the slice is grown. Depending on the characteristics of +the program, it may be desirable to allocate in smaller or larger chunks, or to +put a ceiling on the size of a reallocation. +

+ +

+But most programs don't need complete control, so Go provides a built-in +append function that's good for most purposes; it has the +signature +

+ +
+func append(s []T, x ...T) []T 
+
+ +

+The append function appends the elements x to the end +of the slice s, and grows the slice if a greater capacity is +needed. +

+ +
+a := make([]int, 1)
+// a == []int{0}
+a = append(a, 1, 2, 3)
+// a == []int{0, 1, 2, 3}
+
+ +

+To append one slice to another, use ... to expand the second +argument to a list of arguments. +

+ +
+a := []string{"John", "Paul"}
+b := []string{"George", "Ringo", "Pete"}
+a = append(a, b...) // equivalent to "append(a, b[0], b[1], b[2])"
+// a == []string{"John", "Paul", "George", "Ringo", "Pete"}
+
+ +

+Since the zero value of a slice (nil) acts like a zero-length +slice, you can declare a slice variable and then append to it in a loop: +

+ +
// Filter returns a new slice holding only
+// the elements of s that satisfy f()
+func Filter(s []int, fn func(int) bool) []int {
+    var p []int // == nil
+    for _, i := range s {
+        if fn(i) {
+            p = append(p, i)
+        }
+    }
+    return p
+}
+ +

+A possible "gotcha" +

+ +

+As mentioned earlier, re-slicing a slice doesn't make a copy of the underlying +array. The full array will be kept in memory until it is no longer referenced. +Occasionally this can cause the program to hold all the data in memory when +only a small piece of it is needed. +

+ +

+For example, this FindDigits function loads a file into memory and +searches it for the first group of consecutive numeric digits, returning them +as a new slice. +

+ +
var digitRegexp = regexp.MustCompile("[0-9]+")
+
+func FindDigits(filename string) []byte {
+    b, _ := ioutil.ReadFile(filename)
+    return digitRegexp.Find(b)
+}
+ +

+This code behaves as advertised, but the returned []byte points +into an array containing the entire file. Since the slice references the +original array, as long as the slice is kept around the garbage collector can't +release the array; the few useful bytes of the file keep the entire contents in +memory. +

+ +

+To fix this problem one can copy the interesting data to a new slice before +returning it: +

+ +
func CopyDigits(filename string) []byte {
+    b, _ := ioutil.ReadFile(filename)
+    b = digitRegexp.Find(b)
+    c := make([]byte, len(b))
+    copy(c, b)
+    return c
+}
+ +

+A more concise version of this function could be constructed by using +append. This is left as an exercise for the reader. +

+ +

+Further Reading +

+ +

+Effective Go contains an +in-depth treatment of slices +and arrays, +and the Go language specification +defines slices and their +associated +helper +functions. +

diff --git a/doc/articles/slices_usage_and_internals.tmpl b/doc/articles/slices_usage_and_internals.tmpl new file mode 100644 index 00000000000..94929818b01 --- /dev/null +++ b/doc/articles/slices_usage_and_internals.tmpl @@ -0,0 +1,436 @@ + +{{donotedit}} + +

+Go's slice type provides a convenient and efficient means of working with +sequences of typed data. Slices are analogous to arrays in other languages, but +have some unusual properties. This article will look at what slices are and how +they are used. +

+ +

+Arrays +

+ +

+The slice type is an abstraction built on top of Go's array type, and so to +understand slices we must first understand arrays. +

+ +

+An array type definition specifies a length and an element type. For example, +the type [4]int represents an array of four integers. An array's +size is fixed; its length is part of its type ([4]int and +[5]int are distinct, incompatible types). Arrays can be indexed in +the usual way, so the expression s[n] accesses the nth +element: +

+ +
+var a [4]int
+a[0] = 1
+i := a[0]
+// i == 1
+
+ +

+Arrays do not need to be initialized explicitly; the zero value of an array is +a ready-to-use array whose elements are themselves zeroed: +

+ +
+// a[2] == 0, the zero value of the int type
+
+ +

+The in-memory representation of [4]int is just four integer values laid out sequentially: +

+ +

+ +

+ +

+Go's arrays are values. An array variable denotes the entire array; it is not a +pointer to the first array element (as would be the case in C). This means +that when you assign or pass around an array value you will make a copy of its +contents. (To avoid the copy you could pass a pointer to the array, but +then that's a pointer to an array, not an array.) One way to think about arrays +is as a sort of struct but with indexed rather than named fields: a fixed-size +composite value. +

+ +

+An array literal can be specified like so: +

+ +
+b := [2]string{"Penn", "Teller"}
+
+ +

+Or, you can have the compiler count the array elements for you: +

+ +
+b := [...]string{"Penn", "Teller"}
+
+ +

+In both cases, the type of b is [2]string. +

+ +

+Slices +

+ +

+Arrays have their place, but they're a bit inflexible, so you don't see them +too often in Go code. Slices, though, are everywhere. They build on arrays to +provide great power and convenience. +

+ +

+The type specification for a slice is []T, where T is +the type of the elements of the slice. Unlike an array type, a slice type has +no specified length. +

+ +

+A slice literal is declared just like an array literal, except you leave out +the element count: +

+ +
+letters := []string{"a", "b", "c", "d"}
+
+ +

+A slice can be created with the built-in function called make, +which has the signature, +

+ +
+func make([]T, len, cap) []T
+
+ +

+where T stands for the element type of the slice to be created. The +make function takes a type, a length, and an optional capacity. +When called, make allocates an array and returns a slice that +refers to that array. +

+ +
+var s []byte
+s = make([]byte, 5, 5)
+// s == []byte{0, 0, 0, 0, 0}
+
+ +

+When the capacity argument is omitted, it defaults to the specified length. +Here's a more succinct version of the same code: +

+ +
+s := make([]byte, 5)
+
+ +

+The length and capacity of a slice can be inspected using the built-in +len and cap functions. +

+ +
+len(s) == 5
+cap(s) == 5
+
+ +

+The next two sections discuss the relationship between length and capacity. +

+ +

+The zero value of a slice is nil. The len and +cap functions will both return 0 for a nil slice. +

+ +

+A slice can also be formed by "slicing" an existing slice or array. Slicing is +done by specifying a half-open range with two indices separated by a colon. For +example, the expression b[1:4] creates a slice including elements +1 through 3 of b (the indices of the resulting slice will be 0 +through 2). +

+ +
+b := []byte{'g', 'o', 'l', 'a', 'n', 'g'}
+// b[1:4] == []byte{'o', 'l', 'a'}, sharing the same storage as b
+
+ +

+The start and end indices of a slice expression are optional; they default to zero and the slice's length respectively: +

+ +
+// b[:2] == []byte{'g', 'o'}
+// b[2:] == []byte{'l', 'a', 'n', 'g'}
+// b[:] == b
+
+ +

+This is also the syntax to create a slice given an array: +

+ +
+x := [3]string{"Лайка", "Белка", "Стрелка"}
+s := x[:] // a slice referencing the storage of x
+
+ +

+Slice internals +

+ +

+A slice is a descriptor of an array segment. It consists of a pointer to the +array, the length of the segment, and its capacity (the maximum length of the +segment). +

+ +

+ +

+ +

+Our variable s, created earlier by make([]byte, 5), +is structured like this: +

+ +

+ +

+ +

+The length is the number of elements referred to by the slice. The capacity is +the number of elements in the underlying array (beginning at the element +referred to by the slice pointer). The distinction between length and capacity +will be made clear as we walk through the next few examples. +

+ +

+As we slice s, observe the changes in the slice data structure and +their relation to the underlying array: +

+ +
+s = s[2:4]
+
+ +

+ +

+ +

+Slicing does not copy the slice's data. It creates a new slice value that +points to the original array. This makes slice operations as efficient as +manipulating array indices. Therefore, modifying the elements (not the +slice itself) of a re-slice modifies the elements of the original slice: +

+ +
+d := []byte{'r', 'o', 'a', 'd'}
+e := d[2:] 
+// e == []byte{'a', 'd'}
+e[1] == 'm'
+// e == []byte{'a', 'm'}
+// d == []byte{'r', 'o', 'a', 'm'}
+
+ +

+Earlier we sliced s to a length shorter than its capacity. We can +grow s to its capacity by slicing it again: +

+ +
+s = s[:cap(s)]
+
+ +

+ +

+ +

+A slice cannot be grown beyond its capacity. Attempting to do so will cause a +runtime panic, just as when indexing outside the bounds of a slice or array. +Similarly, slices cannot be re-sliced below zero to access earlier elements in +the array. +

+ +

+Growing slices (the copy and append functions) +

+ +

+To increase the capacity of a slice one must create a new, larger slice and +copy the contents of the original slice into it. This technique is how dynamic +array implementations from other languages work behind the scenes. The next +example doubles the capacity of s by making a new slice, +t, copying the contents of s into t, and +then assigning the slice value t to s: +

+ +
+t := make([]byte, len(s), (cap(s)+1)*2) // +1 in case cap(s) == 0
+for i := range s {
+        t[i] = s[i]
+}
+s = t
+
+ +

+The looping piece of this common operation is made easier by the built-in copy +function. As the name suggests, copy copies data from a source slice to a +destination slice. It returns the number of elements copied. +

+ +
+func copy(dst, src []T) int
+
+ +

+The copy function supports copying between slices of different +lengths (it will copy only up to the smaller number of elements). In addition, +copy can handle source and destination slices that share the same +underlying array, handling overlapping slices correctly. +

+ +

+Using copy, we can simplify the code snippet above: +

+ +
+t := make([]byte, len(s), (cap(s)+1)*2)
+copy(t, s)
+s = t
+
+ +

+A common operation is to append data to the end of a slice. This function +appends byte elements to a slice of bytes, growing the slice if necessary, and +returns the updated slice value: +

+ +{{code "progs/slices.go" `/AppendByte/` `/STOP/`}} + +

+One could use AppendByte like this: +

+ +
+p := []byte{2, 3, 5}
+p = AppendByte(p, 7, 11, 13)
+// p == []byte{2, 3, 5, 7, 11, 13}
+
+ +

+Functions like AppendByte are useful because they offer complete +control over the way the slice is grown. Depending on the characteristics of +the program, it may be desirable to allocate in smaller or larger chunks, or to +put a ceiling on the size of a reallocation. +

+ +

+But most programs don't need complete control, so Go provides a built-in +append function that's good for most purposes; it has the +signature +

+ +
+func append(s []T, x ...T) []T 
+
+ +

+The append function appends the elements x to the end +of the slice s, and grows the slice if a greater capacity is +needed. +

+ +
+a := make([]int, 1)
+// a == []int{0}
+a = append(a, 1, 2, 3)
+// a == []int{0, 1, 2, 3}
+
+ +

+To append one slice to another, use ... to expand the second +argument to a list of arguments. +

+ +
+a := []string{"John", "Paul"}
+b := []string{"George", "Ringo", "Pete"}
+a = append(a, b...) // equivalent to "append(a, b[0], b[1], b[2])"
+// a == []string{"John", "Paul", "George", "Ringo", "Pete"}
+
+ +

+Since the zero value of a slice (nil) acts like a zero-length +slice, you can declare a slice variable and then append to it in a loop: +

+ +{{code "progs/slices.go" `/Filter/` `/STOP/`}} + +

+A possible "gotcha" +

+ +

+As mentioned earlier, re-slicing a slice doesn't make a copy of the underlying +array. The full array will be kept in memory until it is no longer referenced. +Occasionally this can cause the program to hold all the data in memory when +only a small piece of it is needed. +

+ +

+For example, this FindDigits function loads a file into memory and +searches it for the first group of consecutive numeric digits, returning them +as a new slice. +

+ +{{code "progs/slices.go" `/digit/` `/STOP/`}} + +

+This code behaves as advertised, but the returned []byte points +into an array containing the entire file. Since the slice references the +original array, as long as the slice is kept around the garbage collector can't +release the array; the few useful bytes of the file keep the entire contents in +memory. +

+ +

+To fix this problem one can copy the interesting data to a new slice before +returning it: +

+ +{{code "progs/slices.go" `/CopyDigits/` `/STOP/`}} + +

+A more concise version of this function could be constructed by using +append. This is left as an exercise for the reader. +

+ +

+Further Reading +

+ +

+Effective Go contains an +in-depth treatment of slices +and arrays, +and the Go language specification +defines slices and their +associated +helper +functions. +

diff --git a/doc/progs/run b/doc/progs/run index 9cb6f8d79f1..2a76d6b2da0 100755 --- a/doc/progs/run +++ b/doc/progs/run @@ -61,6 +61,7 @@ for i in \ $effective_go \ $error_handling \ $go_tutorial \ + slices.go \ go1.go \ ; do $GC $i diff --git a/doc/progs/slices.go b/doc/progs/slices.go new file mode 100644 index 00000000000..be4322a3282 --- /dev/null +++ b/doc/progs/slices.go @@ -0,0 +1,55 @@ +package main + +import ( + "io/ioutil" + "regexp" +) + +func AppendByte(slice []byte, data ...byte) []byte { + m := len(slice) + n := m + len(data) + if n > cap(slice) { // if necessary, reallocate + // allocate double what's needed, for future growth. + newSlice := make([]byte, (n+1)*2) + copy(newSlice, slice) + slice = newSlice + } + slice = slice[0:n] + copy(slice[m:n], data) + return slice +} + +// STOP OMIT + +// Filter returns a new slice holding only +// the elements of s that satisfy f() +func Filter(s []int, fn func(int) bool) []int { + var p []int // == nil + for _, i := range s { + if fn(i) { + p = append(p, i) + } + } + return p +} + +// STOP OMIT + +var digitRegexp = regexp.MustCompile("[0-9]+") + +func FindDigits(filename string) []byte { + b, _ := ioutil.ReadFile(filename) + return digitRegexp.Find(b) +} + +// STOP OMIT + +func CopyDigits(filename string) []byte { + b, _ := ioutil.ReadFile(filename) + b = digitRegexp.Find(b) + c := make([]byte, len(b)) + copy(c, b) + return c +} + +// STOP OMIT