Go Basics Flashcards
Create a map
m := map[string]int{}
Iterate through map
for k, v := range myMap { … }
Check if map contains a key
val, ok := myMap[key]
Absolute value function
import “math”
math.Abs(n)
* note that this takes and returns a float64 value
Sort an array of ints
import “sort”
sort.Ints(array)
// This sort happens in place
Create a 2D slice
mySlice := make([][]int, outerArrayLength)
mySlice[i] := make([]int, innerArrayLength)
// slices can only be 1D so you must define size of inner arrays
// you define the array from the outside-in since you can have multiple dimensions
https://golangbyexample.com/two-dimensional-array-slice-golang/
Print the value of a variable
import “fmt”
fmt.Printf(“%v”, variable)
// use “%+v” to add field names to structs
Print hello world
import “fmt”
fmt.Println(“hello world”)
Take the square root of a number
import “math”
math.Sqrt(n)
* input and output is float64
Write a function that takes 2 integers as parameters and returns 2 integers
func myfunction(x, y int) (int, int) { … }
Define the variable i equal to 1 outside of a function
var i int = 1
(the := construct is only available inside a function)
Convert the variable i of type integer into a floating number
f := float64(i)
Declare a constant variable
const Hello string = “hello”
Create a while loop
for x < 100 { x += 1 }
Create an infinite loop
for { … }
Return x to the nth power
import “math”
math.Pow(x, n)
Write a switch statement
switch name {
case “matt”:
fmt.Println(“Hello Matt!”)
case “bob”:
fmt.Println(“Hello Bob!”)
default:
fmt.Println(“hello”)
}
or
switch {
case name == “matt”:
…
What is a pointer?
It holds the memory address of a variable
Initialize a pointer for a new variable p of type integer
var p *int
Generate a pointer for the existing variable p
i = &p
Create a pointer for the integer i, print it’s value through the pointer, and set i through the pointer
p = &i
fmt.Println(*p) // read i through the pointer p
*p = 21 // set i through the pointer p
What is a struct?
A collection of fields
Declare a variable as an array of 10 integers
var x [10]int
OR
x := [10]int{}
OR
x := make([]int, 10)
Add the number 1 to the end of a slice
s = append(s, 1)
Loop through an array
for i, v := range arr {}
Remove the key “k” from the map “m”
delete(m, k)
Check if the key “k” is present in the map “m”
elem, ok := m[k]
Create an add method for the type Num struct { X, Y int } and use it
func (n Num) Add() int { return n.X + n.Y }
n := Num{ X: 3, Y: 4 }
n.Add()
The Add method has a receiver of type Num called n. A method is just a function with a receiver argument
Define a method that returns the absolute value of an integer and use it
type MyInt int
func (i MyInt) Abs() int {
if i < 0 {
return int(-i)
}
return int(i)
}
i := MyInt(-2)
i.Abs()
// Return values must be converted from MyInt to Int
Create a method that doubles the value of an integer in place
type MyInt int
func (i *MyInt) Double() {
*i = *i * 2
}
Write a function called Scale that takes 2 parameters: (1) type Vertex Struct { X, Y float64 } and (2) a number to scale it by. The function should modify the original struct values without using a receiver. Then use the function.
func Scale (v *Vertex, f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
v := Vertex{ X: 1, Y: 2 }
Scale(&v, 10)
When should pointer receivers be used?
When (1) the method should modify the value that its receiver points to or (2) to avoid copying the value (especially if large) on each method call
What’s the difference between pointer receivers and value receivers?
Methods with “pointer receivers” can modify the value to which the receiver points, which is more common than “value receivers”. Value receivers operate on a copy of the original value, which is the same as for any other function argument.
Receivers (pointers or values) conveniently take either a value or a pointer as the receiver when called, unlike functions. In other words, methods are more flexible than functions. All methods on a given type should have either value or pointer receivers, but not a mixture of both
What is an interface?
A collection of methods
Reverse a word (eg hello becomes olleh)
reverse := []byte{}
for i := len(word)-1; i >= 0; i– {
reverse = append(reverse, word[i])
}
OR
package main
import “fmt”
func main () {
word := []rune(“hello”)
first := 0
last := len(word) - 1
for first < last {
word[first], word[last] = word[last], word[first]
first++
last–
}
fmt.Println(string(word))
}
- Rune is more common than Byte
Convert integer to string
import “strconv”
strconv.Itoa(n)
What is a rune type?
Unicode characters
Convert string to rune
[]rune(myString)
Convert runes to string
string(myRunes)
What is a method?
A function with a receiver argument
What’s the different between “func (v Vertex) MyFun() {}” and “func (v *Vertex) MyFun() {}”
The latter can modify its receiver. If there isn’t a pointer receiver then the passed receiver is a copy
What is a byte type?
An ASCII character
How should each Go file start?
package main
func main () {
. . .
}
How to convert string to integer?
import “strconv”
n, error := strconv.ParseInt(“101”, 10, 64)
// 10 is the base; 64 is the bytes (could also be 32)
How to traverse a linked list?
type LinkedList struct {
Value int
Next *LinkedList
}
currentNode := linkedList
for currentNode != nil {
currentNode = currentNode.Next
}
return linkedList
Round a floating number up to nearest integer
import “math”
math.Ceil(n)
Create a breadth-first search
package main
type Node struct {
Name string
Children []*Node
}
func (n Node) BreadthFirstSearch(array []string) []string {
queue := []Node{n}
for len(queue) > 0 {
current := queue[0]
array = append(array, current.Name)
queue = queue[1:]
for _, child := range current.Children {
queue = append(queue, child)
}
}
return array
}
Create a depth-first search
type Node struct {
Name string
Children []*Node
}
func (n *Node) DepthFirstSearch(array []string) []string {
array = append(array, n.Name)
for _, child := range n.Children {
array = child.DepthFirstSearch(array)
}
return array
}
Sort a 2D array by first values (integers) in inner arrays
import “sort”
sort.Slice(myArray, func(i, j ints) bool {
return myArray[i][0] < myArray[j][0]
})
Sort the following by age
people := []struct {
Name string
Age int
}{
{“Matt”, 38},
{“Megan”, 39},
}
import “sort”
sort.Slice(people, func (i, j int) bool {
return people[i].Age < people[j].Age
})
Replace words in a string
import “strings”
newStr := strings.Replace(oldString, “old”, “new”, -1)
// the last number is how many times to make the replacement where -1 is unlimited
Generate a random integer from 0 to 100
import “math/rand”
rand.Intn(101)
// n cannot be 0
Cast an interface value (eg variable name value
) to a concrete type (eg integer)
v, ok := value.(int)
Make an HTTP request
import “net/http”
resp, err := http.Get(“https://example.com”)
if err != nil {
Check if a variable (eg circle) is an instance of an interface (eg Shape) and cast it into its underlying concrete type (shape) if it is
c, ok := circle.(Shape)
Use a type switch statement to cast a variable to the correct type
switch v := num.(type) {
case int:
fmt.Printf(“%T\n”, v)
case string:
fmt.Printf(“%T\n”, v)
default:
fmt.Printf(“%T\n”, v)
}
Define a Firetruck type that extends a Car type
type Car struct {
make string
model string
}
type Truck struct {
Car
bedSize int
}
truck := Truck{
Car: Car{
make: “Ford”,
model: “F150”,
},
bedSize: 8,
}
fmt.Println(truck.make)
# An embedded struct’s fields are accessed at the top level, unlike nested structs
Define a function with named return values
func myFunc(x int) (myReturnValue int) { … }
Define more than 1 constant variable at a time
const (
planFree = “free”
planPro = “pro”
)
Define an error
import “errors”
errors.New(“this is an error message”)
Write a function with an arbitrary number of final arguments and then call that function using the spread operator
func main() {
names := []string{“a”, “b”, “c”}
test(names…)
}
func test(a …string) {
for _, v := range a {
fmt.Println(v)
}
}
Append one array (eg y) to another (eg x)
append(x, y…)
Add multiple items to an array
append(x, 1, 2, 3)
Check if an array contains a value
numbers := []int{0, 42, 10, 8}
slices.Contains(numbers, 10) // true
Create a one-liner if statement condition that also defines a value in the if statement
if v, ok := getSomething(); ok { … }