CMU 15-112: Fundamentals of Programming and Computer Science
Class Notes: Sequences in Go
- Strings
package main import "fmt" func main() { s := "hello" // Strings are defined with double quotes c := 'c' // Characters (runes) are defined with single quotes fmt.Println(s) // prints "hello" fmt.Println(c) // prints ... 99? fmt.Println() /* Runes in Go are integers representing the ord of the character. To print the character itself we can cast it to a string */ fmt.Println(string(c)) }
Looping over strings via indexpackage main import "fmt" func main() { s := "Don't forget to be awesome" for i := 0; i < len(s); i += 1 { // Indexing into a string gives us a character fmt.Println(s[i], string(s[i])) } }
Looping over strings with range
- Slices
package main import "fmt" func main() { /* In go, the closest structure to a Python list is called a slice. We can statically allocate a slice like this. Slices always have a defined type. You can read []int as "a slice of integers" */ a := []int{1, 2, 3, 4, 5} fmt.Println(a) }
Creating slices with makepackage main import "fmt" func main() { /* This line makes an empty slice with 5 elements. By default the slice is filled with zeros */ a := make([]int, 5) fmt.Println(a) }
Appending to slicespackage main import "fmt" func main() { a := make([]int, 0) // An empty slice // Append usually returns an alias, but sometimes returns a shallow copy a = append(a, 112) a = append(a, 42) fmt.Println(a) }
Looping over slices by indexpackage main import "fmt" func main() { a := []string{"a", "b", "c", "d"} for i := 0; i < len(a); i += 1 { fmt.Println(a[i]) } }
Looping over slices with rangepackage main import "fmt" func main() { a := []string{"carpe", "diem"} for _, word := range a { fmt.Println(word) } }
Concatenating Slicespackage main import "fmt" /* In Go, there is no + operator between slices. Instead, we use the following synatx for adding slices */ func main() { a := []int{1,2,3} b := []int{4,5,6} c := append(a, b...) // Adds each element of b as an argument to append fmt.Println(c) }
Slice Equalitypackage main import ( "fmt" "github.com/CMU15-112/golang" ) /* Slices can't be compared directly with == in Go. Instead, use cs112.Equals */ func main() { fmt.Println(cs112.Equals([]int{1,2}, []int{1,2})) fmt.Println(cs112.Equals([]int{1,2}, []int{3,4})) }
Utility Functionspackage main import ( "fmt" "github.com/CMU15-112/golang" ) /* cs112 exposes MaxSlice, MinSlice, Index, Count, and Contains functions on slices */ func main() { fmt.Println(cs112.MaxSlice([]int{8,7,6,9,8})) // 8 fmt.Println(cs112.MaxSlice([]string{"a", "b", "z"})) // "z" fmt.Println(cs112.MinSlice([]int{1,5,4,-3})) // -3 fmt.Println() fmt.Println(cs112.Index([]int{1,2,9,8}, 2)) // 1 fmt.Println(cs112.Index([]int{}, 42)) // -1 fmt.Println() fmt.Println(cs112.Count([]int{1,2,2,2,3,4,4,5}, 2)) // 3 fmt.Println() fmt.Println(cs112.Contains([]int{1,2,3}, 3)) // true fmt.Println(cs112.Contains([]string{"b", "c", "hello"}, "hello")) // true fmt.Println(cs112.Contains([][]int{{1,2}, {3,4}}, []int{3,4})) // true }
- 2D Slices
package main import "fmt" func main() { /* We can statically allocate slices like this */ a := [][]int{ {1, 2, 3, 4}, {5, 6, 7, 8}, } /* You can read [][]int as "slice of integer slices" like a "list of lists of numbers" */ for row := 0; row < len(a); row += 1 { for col := 0; col < len(a[0]); col += 1 { fmt.Print(a[row][col], " ") } fmt.Println() } }
Creating an empty 2d slicepackage main import "fmt" func main() { a := make([][]int, 5) fmt.Println(a) }
Dynamically creating a 2d slicepackage main import "fmt" func make2dList(rows, cols int) [][]int { result := make([][]int, rows) // an empty 2d list of numbers for row := 0; row < rows; row += 1 { result[row] = make([]int, cols) } return result } func printGrid(grid [][]int) { for _, row := range grid { fmt.Println(row) } } func main() { n := 5 grid := make2dList(n, n) for i := 0; i < n; i += 1 { grid[i][i] = 1 } printGrid(grid) }
package main
import "fmt"
func main() {
/* We can loop over a range in Go just like in Python. The range gives us
index, character pairs */
for index, character := range "hello" {
fmt.Println(index, character, string(character))
}
}
Ignoring the index
package main
import "fmt"
func main() {
/* If we don't use the index but still name it, we get a compilation error.
We can fix this by replacing the index variable name with an underscore */
//for _, character := range "hello" {
for index, character := range "hello" {
fmt.Println(string(character))
}
}
Slicing
package main
import "fmt"
// Strings can be sliced [start:stop] just like in Python
func main() {
s := "Don't forget to be awesome"
fmt.Println(s[16:])
fmt.Println(s[19:22], "inspiring")
}
Converting between runes and strings
package main
import "fmt"
func main() {
s := "a" // this is a string
// We can get runes out of a string by looping over it
for _, r := range s {
fmt.Println(r)
}
// Or by indexing into it
fmt.Println(s[0])
r := 'a' // this is a rune
fmt.Println(string(r)) // which we can cast to a string
}
The strings module
package main
import (
"fmt"
"strings"
)
func main() {
/* The strings module contains a variety of convenience methods for
strings. See here for more: https://golang.org/pkg/strings/ */
s := "Don't forget to be awesome"
fmt.Println(strings.Contains(s, "awesome"))
fmt.Println(strings.Index(s, "be"))
fmt.Println(strings.Count(s, " "))
}