content: rewrite slices section
This rewrite introduces slices in terms of arrays,
before introducing make. I think it flows more nicely.
Fixes golang/go#13883
Fixes golang/go#14893
Change-Id: Idd0c6de29c0207d755cac673e580efee6c34a7b2
Reviewed-on: https://go-review.googlesource.com/21358
Reviewed-by: Chris Broadfoot <cbro@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
diff --git a/content/moretypes.article b/content/moretypes.article
index a410fb5..bfae74f 100644
--- a/content/moretypes.article
+++ b/content/moretypes.article
@@ -64,6 +64,7 @@
.play moretypes/struct-literals.go
+
* Arrays
The type `[n]T` is an array of `n` values of type `T`.
@@ -80,45 +81,110 @@
.play moretypes/array.go
+
* Slices
-A slice points to an array of values and also includes a length.
+An array has a fixed size.
+A slice, on the other hand, is a dynamically-sized,
+flexible view into the elements of an array.
+In practice, slices are much more common than arrays.
-`[]T` is a slice with elements of type `T`.
+The type `[]T` is a slice with elements of type `T`.
-`len(primes)` returns the length of slice `primes`.
+This expression creates a slice of the first five elements of the array `a`:
+
+ a[0:5]
+
.play moretypes/slices.go
-* Slices of Slices
-Slices can contain any type, including other slices.
+* Slices are like references to arrays
-.play moretypes/slices-of-slice.go
+A slice does not store any data,
+it just describes a section of an underlying array.
-* Slicing slices
+Changing the elements of a slice modifies the
+corresponding elements of its underlying array.
-Slices can be re-sliced, creating a new slice value that points to the same array.
+Other slices that share the same underlying array will see those changes.
-The expression
+.play moretypes/slices-pointers.go
- s[lo:hi]
-evaluates to a slice of the elements from `lo` through `hi-1`, inclusive. Thus
+* Slice literals
- s[lo:lo]
+A slice literal is like an array literal without the length.
-is empty and
+This is an array literal:
- s[lo:lo+1]
+ [3]bool{true, true, false}
-has one element.
+And this creates the same array as above,
+then builds a slice that references it:
-.play moretypes/slicing-slices.go
+ []bool{true, true, false}
-* Making slices
+.play moretypes/slice-literals.go
-Slices are created with the `make` function. It works by allocating a zeroed array and returning a slice that refers to that array:
+
+* Slice defaults
+
+When slicing, you may omit the high or low bounds to use their defaults instead.
+
+The default is zero for the low bound and the length of the slice for the high bound.
+
+For the array
+
+ var a [10]int
+
+these slice expressions are equivalent:
+
+ a[0:10]
+ a[:10]
+ a[0:]
+ a[:]
+
+.play moretypes/slice-bounds.go
+
+
+* Slice length and capacity
+
+A slice has both a _length_ and a _capacity_.
+
+The length of a slice is the number of elements it contains.
+
+The capacity of a slice is the number of elements in the underlying array,
+counting from the first element in the slice.
+
+The length and capacity of a slice `s` can be obtained using the expressions
+`len(s)` and `cap(s)`.
+
+You can extend a slice's length by re-slicing it,
+provided it has sufficient capacity.
+Try changing one of the slice operations in the example program to extend it
+beyond its capacity and see what happens.
+
+.play moretypes/slice-len-cap.go
+
+
+* Nil slices
+
+The zero value of a slice is `nil`.
+
+A nil slice has a length and capacity of 0
+and has no underlying array.
+
+.play moretypes/nil-slices.go
+
+
+* Creating a slice with make
+
+Slices can be created with the built-in `make` function;
+this is how you create dynamically-sized arrays.
+
+The `make` function allocates a zeroed array
+and returns a slice that refers to that array:
a := make([]int, 5) // len(a)=5
@@ -131,15 +197,15 @@
.play moretypes/making-slices.go
-* Nil slices
-The zero value of a slice is `nil`.
+* Slices of slices
-A nil slice has a length and capacity of 0.
+Slices can contain any type, including other slices.
-.play moretypes/nil-slices.go
+.play moretypes/slices-of-slice.go
-* Adding elements to a slice
+
+* Appending to a slice
It is common to append new elements to a slice, and so Go provides a built-in
`append` function. The [[https://golang.org/pkg/builtin/#append][documentation]]
@@ -161,6 +227,7 @@
.play moretypes/append.go
+
* Range
The `range` form of the `for` loop iterates over a slice or map.
diff --git a/content/moretypes/array.go b/content/moretypes/array.go
index 8626743..8d73573 100644
--- a/content/moretypes/array.go
+++ b/content/moretypes/array.go
@@ -10,4 +10,7 @@
a[1] = "World"
fmt.Println(a[0], a[1])
fmt.Println(a)
+
+ primes := [6]int{2, 3, 5, 7, 11, 13}
+ fmt.Println(primes)
}
diff --git a/content/moretypes/slice-bounds.go b/content/moretypes/slice-bounds.go
new file mode 100644
index 0000000..1ba3963
--- /dev/null
+++ b/content/moretypes/slice-bounds.go
@@ -0,0 +1,18 @@
+// +build OMIT
+
+package main
+
+import "fmt"
+
+func main() {
+ s := []int{2, 3, 5, 7, 11, 13}
+
+ s = s[1:4]
+ fmt.Println(s)
+
+ s = s[:2]
+ fmt.Println(s)
+
+ s = s[1:]
+ fmt.Println(s)
+}
diff --git a/content/moretypes/slice-len-cap.go b/content/moretypes/slice-len-cap.go
new file mode 100644
index 0000000..a1c5764
--- /dev/null
+++ b/content/moretypes/slice-len-cap.go
@@ -0,0 +1,26 @@
+// +build OMIT
+
+package main
+
+import "fmt"
+
+func main() {
+ s := []int{2, 3, 5, 7, 11, 13}
+ printSlice(s)
+
+ // Slice the slice to give it zero length.
+ s = s[:0]
+ printSlice(s)
+
+ // Extend its length.
+ s = s[:4]
+ printSlice(s)
+
+ // Drop its first two values.
+ s = s[2:]
+ printSlice(s)
+}
+
+func printSlice(s []int) {
+ fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
+}
diff --git a/content/moretypes/slice-literals.go b/content/moretypes/slice-literals.go
new file mode 100644
index 0000000..5a98010
--- /dev/null
+++ b/content/moretypes/slice-literals.go
@@ -0,0 +1,26 @@
+// +build OMIT
+
+package main
+
+import "fmt"
+
+func main() {
+ q := []int{2, 3, 5, 7, 11, 13}
+ fmt.Println(q)
+
+ r := []bool{true, false, true, true, false, true}
+ fmt.Println(r)
+
+ s := []struct {
+ i int
+ b bool
+ }{
+ {2, true},
+ {3, false},
+ {5, true},
+ {7, true},
+ {11, false},
+ {13, true},
+ }
+ fmt.Println(s)
+}
diff --git a/content/moretypes/slices-pointers.go b/content/moretypes/slices-pointers.go
new file mode 100644
index 0000000..193b463
--- /dev/null
+++ b/content/moretypes/slices-pointers.go
@@ -0,0 +1,23 @@
+// +build OMIT
+
+package main
+
+import "fmt"
+
+func main() {
+ names := [4]string{
+ "John",
+ "Paul",
+ "George",
+ "Ringo",
+ }
+ fmt.Println(names)
+
+ a := names[0:2]
+ b := names[1:3]
+ fmt.Println(a, b)
+
+ b[0] = "XXX"
+ fmt.Println(a, b)
+ fmt.Println(names)
+}
diff --git a/content/moretypes/slices.go b/content/moretypes/slices.go
index 385283c..7720f84 100644
--- a/content/moretypes/slices.go
+++ b/content/moretypes/slices.go
@@ -5,10 +5,8 @@
import "fmt"
func main() {
- primes := []int{2, 3, 5, 7, 11, 13}
- fmt.Println("primes ==", primes)
+ primes := [6]int{2, 3, 5, 7, 11, 13}
- for i := 0; i < len(primes); i++ {
- fmt.Printf("primes[%d] == %d\n", i, primes[i])
- }
+ var s []int = primes[1:4]
+ fmt.Println(s)
}
diff --git a/content/moretypes/slicing-slices.go b/content/moretypes/slicing-slices.go
deleted file mode 100644
index 27e1aef..0000000
--- a/content/moretypes/slicing-slices.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// +build OMIT
-
-package main
-
-import "fmt"
-
-func main() {
- s := []int{2, 3, 5, 7, 11, 13}
- fmt.Println("s ==", s)
- fmt.Println("s[1:4] ==", s[1:4])
-
- // missing low index implies 0
- fmt.Println("s[:3] ==", s[:3])
-
- // missing high index implies len(s)
- fmt.Println("s[4:] ==", s[4:])
-}