diff --git a/117-Slices/slices-0.gop b/117-Slices/slices-0.gop deleted file mode 100644 index 96fedbc..0000000 --- a/117-Slices/slices-0.gop +++ /dev/null @@ -1,53 +0,0 @@ -// _Slices_ are a key data type in Go+, giving a more -// powerful interface to sequences than arrays. - -# Slice foundations - -// Unlike arrays, slices are typed only by the -// elements they contain (not the number of elements). -// To create an empty slice with non-zero length, use -// the builtin `make`. Here we make a slice of -// `string`s of length `3` (initially zero-valued). -s := make([]string, 3) -println "emp:", s - -// We can set and get just like with arrays. -s[0] = "a" -s[1] = "b" -s[2] = "c" -println "set:", s -println "get:", s[2] - -// `len` returns the length of the slice as expected. -println "len:", len(s) - -// In addition to these basic operations, slices -// support several more that make them richer than -// arrays. One is the builtin `append`, which -// returns a slice containing one or more new values. -// Note that we need to accept a return value from -// `append` as we may get a new slice value. -s = append(s, "d") -s = append(s, "e", "f") -println "apd:", s - -// Slices can also be `copy`'d. Here we create an -// empty slice `c` of the same length as `s` and copy -// into `c` from `s`. -c := make([]string, len(s)) -copy c, s -println "cpy:", c - -// Slices support a "slice" operator with the syntax -// `slice[low:high]`. For example, this gets a slice -// of the elements `s[2]`, `s[3]`, and `s[4]`. -l := s[2:5] -println "sl1:", l - -// This slices up to (but excluding) `s[5]`. -l = s[:5] -println "sl2:", l - -// And this slices up from (and including) `s[2]`. -l = s[2:] -println "sl3:", l diff --git a/117-Slices/slices-01.gop b/117-Slices/slices-01.gop new file mode 100644 index 0000000..cfedcbb --- /dev/null +++ b/117-Slices/slices-01.gop @@ -0,0 +1,18 @@ +# Slice literals in Go+ style +// A slice is a collection of data elements of the same type. A slice literal is a list of expressions surrounded by square brackets. An individual element can be accessed using an index expression. Indexes start from 0. +// +// In go+, you can get slice length directly from len method, and you can casting slice literals: + +f64 := []float64([1, 2, 3]) // []float64 +println(f64, f64.len) // get length by len method + +nums := [1, 2, 3] +println nums // [1 2 3] +println nums.len // 3, go+ support +println nums[0] // 1 +println nums[1:3] // [2 3] +println nums[:2] // [1 2] +println nums[2:] // [3] + +nums[1] = 5 +println nums // [1 5 3] diff --git a/117-Slices/slices-02.gop b/117-Slices/slices-02.gop new file mode 100644 index 0000000..1ce2019 --- /dev/null +++ b/117-Slices/slices-02.gop @@ -0,0 +1,6 @@ +# Slice +// 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. +// +// The type []T is a slice with elements of type T. +// +// A slice is formed by specifying two indices, a low and high bound, separated by a colon: a[low : high]. This selects a half-open range which includes the first element, but excludes the last one. diff --git a/117-Slices/slices-03.gop b/117-Slices/slices-03.gop new file mode 100644 index 0000000..6d498ee --- /dev/null +++ b/117-Slices/slices-03.gop @@ -0,0 +1,22 @@ +# Slices are like references to arrays +// A slice does not store any data, it just describes a section of an underlying array. +// +// Changing the elements of a slice modifies the corresponding elements of its underlying array. +// +// Other slices that share the same underlying array will see those changes. + +names := [4]string{ + "John", + "Paul", + "George", + "Ringo", +} +println names + +a := names[0:2] +b := names[1:3] +println a, b + +b[0] = "XXX" +println a, b +println names diff --git a/117-Slices/slices-04.gop b/117-Slices/slices-04.gop new file mode 100644 index 0000000..046a5ae --- /dev/null +++ b/117-Slices/slices-04.gop @@ -0,0 +1,27 @@ +# Slice literals +// A slice literal is like an array literal without the length. +//
+// This is an array literal:
+// [3]bool{true, true, false}
+// And this creates the same array as above, then builds a slice that references it:
+// []bool{true, true, false}
+//
+
+q := []int{2, 3, 5, 7, 11, 13}
+println q
+
+r := []bool{true, false, true, true, false, true}
+println r
+
+s := []struct {
+ i int
+ b bool
+}{
+ {2, true},
+ {3, false},
+ {5, true},
+ {7, true},
+ {11, false},
+ {13, true},
+}
+println s
diff --git a/117-Slices/slices-05.gop b/117-Slices/slices-05.gop
new file mode 100644
index 0000000..6429fbd
--- /dev/null
+++ b/117-Slices/slices-05.gop
@@ -0,0 +1,23 @@
+# 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[:] +//+s := []int{2, 3, 5, 7, 11, 13} + +s = s[1:] +println s + +s = s[1:4] +println s + +s = s[:2] +println s diff --git a/117-Slices/slices-06.gop b/117-Slices/slices-06.gop new file mode 100644 index 0000000..215d214 --- /dev/null +++ b/117-Slices/slices-06.gop @@ -0,0 +1,26 @@ +# 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. + +func printSlice(s []int) { + printf "len=%d cap=%d %v\n", len(s), cap(s), s +} + +s := []int{2, 3, 5, 7, 11, 13} +printSlice s + +s = s[:0] // Slice the slice to give it zero length. +printSlice s + +s = s[:4] // Extend its length. +printSlice s + +s = s[2:] // Drop its first two values. +printSlice s diff --git a/117-Slices/slices-07.gop b/117-Slices/slices-07.gop new file mode 100644 index 0000000..286143a --- /dev/null +++ b/117-Slices/slices-07.gop @@ -0,0 +1,12 @@ +# 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. + +var s []int + +println s, len(s), cap(s) + +if s == nil { + println "nil!" +} diff --git a/117-Slices/slices-08.gop b/117-Slices/slices-08.gop new file mode 100644 index 0000000..d293e4d --- /dev/null +++ b/117-Slices/slices-08.gop @@ -0,0 +1,29 @@ +# 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 +//To specify a capacity, pass a third argument to make: +//b := make([]int, 0, 5) // len(b)=0, cap(b)=5 +//b = b[:cap(b)] // len(b)=5, cap(b)=5 +//b = b[1:] // len(b)=4, cap(b)=4 +//+ +func printSlice(s string, x []int) { + printf "%s len=%d cap=%d %v\n", + s, len(x), cap(x), x +} + +a := make([]int, 5) +printSlice "a", a + +b := make([]int, 0, 5) +printSlice "b", b + +c := b[:2] +printSlice "c", c + +d := c[2:5] +printSlice "d", d diff --git a/117-Slices/slices-09.gop b/117-Slices/slices-09.gop new file mode 100644 index 0000000..4841ce9 --- /dev/null +++ b/117-Slices/slices-09.gop @@ -0,0 +1,23 @@ +# Slices of slices +// Slices can contain any type, including other slices. +// Create a tic-tac-toe board. + +import ( + "strings" +) + +board := [][]string{ + []string{"_", "_", "_"}, + []string{"_", "_", "_"}, + []string{"_", "_", "_"}, +} + +board[0][0] = "X" // The players take turns. +board[2][2] = "O" +board[1][2] = "X" +board[1][0] = "O" +board[0][2] = "X" + +for i := 0; i < len(board); i++ { + printf "%s\n", strings.join(board[i], " ") +} diff --git a/117-Slices/slices-1.gop b/117-Slices/slices-1.gop deleted file mode 100644 index 619e07b..0000000 --- a/117-Slices/slices-1.gop +++ /dev/null @@ -1,3 +0,0 @@ -# Slice literals in Go+ style - -## TODO diff --git a/117-Slices/slices-10.gop b/117-Slices/slices-10.gop new file mode 100644 index 0000000..8566772 --- /dev/null +++ b/117-Slices/slices-10.gop @@ -0,0 +1,27 @@ +# Appending to a slice +// It is common to append new elements to a slice, and so Go provides a built-in append function. The documentation of the built-in package describes append. +// +// func append(s []T, vs ...T) []T +// +// The first parameter s of append is a slice of type T, and the rest are T values to append to the slice. +// +// The resulting value of append is a slice containing all the elements of the original slice plus the provided values. +// +// If the backing array of s is too small to fit all the given values a bigger array will be allocated. The returned slice will point to the newly allocated array. + +func printSlice(s []int) { + printf "len = %d cap = %d %v\n", len(s), cap(s), s +} + +var s []int + +printSlice s + +s = append(s, 0) // append works on nil slices. +printSlice s + +s = append(s, 1) // The slice grows as needed. +printSlice s + +s = append(s, 2, 3, 4) // We can add more than one element at a time. +printSlice s diff --git a/117-Slices/slices-11.gop b/117-Slices/slices-11.gop new file mode 100644 index 0000000..a81116a --- /dev/null +++ b/117-Slices/slices-11.gop @@ -0,0 +1,10 @@ +# Range +// The range form of the for loop iterates over a slice or map. +// +// When ranging over a slice, two values are returned for each iteration. The first is the index, and the second is a copy of the element at that index. + +var pow = []int{1, 2, 4, 8, 16, 32, 64, 128} + +for i, v := range pow { + printf "2**%d = %d\n", i, v +} diff --git a/117-Slices/slices-12.gop b/117-Slices/slices-12.gop new file mode 100644 index 0000000..968e43f --- /dev/null +++ b/117-Slices/slices-12.gop @@ -0,0 +1,17 @@ +# Range continued +// +//
+// You can skip the index or value by assigning to _. +// for i, _ := range pow +// for _, value := range pow +// If you only want the index, you can omit the second variable. +// for i := range pow +//+ +pow := make([]int, 10) +for i := range pow { + pow[i] = 1 << uint(i) // == 2**i +} +for _, value := range pow { + printf "%d\n", value +} diff --git a/117-Slices/slices-2.gop b/117-Slices/slices-2.gop deleted file mode 100644 index a5b1abd..0000000 --- a/117-Slices/slices-2.gop +++ /dev/null @@ -1,6 +0,0 @@ -# Slice literals in Go style - -// We can declare and initialize a variable for slice -// in a single line as well. -t := []string{"g", "h", "i"} -println "dcl:", t diff --git a/117-Slices/slices-3.gop b/117-Slices/slices-3.gop deleted file mode 100644 index dfc0090..0000000 --- a/117-Slices/slices-3.gop +++ /dev/null @@ -1,20 +0,0 @@ -# Slice advance - -buf := make([]byte, 0, 128) -buf = append(buf, 'H', 'e', 'l', 'l', 'o') -buf = append(buf, ' ') -buf = append(buf, "world"...) -println string(buf) - -// Slices can be composed into multi-dimensional data -// structures. The length of the inner slices can -// vary, unlike with multi-dimensional arrays. -twoD := make([][]int, 3) -for i := 0; i < 3; i++ { - innerLen := i + 1 - twoD[i] = make([]int, innerLen) - for j := 0; j < innerLen; j++ { - twoD[i][j] = i + j - } -} -println "2d: ", twoD