Learning golang 02 - DS and algo
Data structures from the go tour
Arrays
The type [n]T
creates an array of n values of type T.
var a [10]int
//Creates an array 'a' of int type with size 10
Slices
An array has a fixed size. A slice is dynamically-sized
The type []T
is a slice of elements with type T
Slices require high and low point in the array [low:high]
package main
import "fmt"
func main(){
v := [6]int{1,2,3,4,5,6}
var s []int = v[2:5]
fmt.Println(s)
//prints [3,4,5,6]
}
Slices are reference to arrays
If a value in a slice is changed, the underlying array changes as well Other slices that shares those slices will see the changes too
package main
import "fmt"
func main(){
names := [4]{
"Alice", "bob", "Cathie", "David"
}
fmt.Println(names)
a:=names[0:2]
b:=names[1:3]
fmt.Println(a,b)
//prints ["Alice","bob"] ["Cathie", "David"]
b[0] = "XXX"
fmt.Println(a, b)
fmt.Println(names)
}
Slice defaults
When slicing, the higher or lower bounds can be ignored. Similar to python
s := [10]int{1,2,3,4,5,6,7,8,9,0}
// s[0:10] = s[:] = s[0:] = s[:10]
Slice length and capacity
length is the length of the slice, it can be got using len(s)
capacity is the length of the underlying array, it can be got using. cap(s)
Null Slices
The zero value of a slice is nil. A nil slice has a length and capacity of zero and has no underlying array.
package main
import "fmt"
func main(){
var s[]int //creating a slice
fmt.Println(s, len(s), cap(s))
if s == Nil {
fmt.Println("nil")
}
}
Creating a slice with make (Dynamic array)
This is how you create a dynamic array
var a:= make([]int, 5)
To specify capacity a third argument can be passed
var b:=make([int])
Slices of slices
Slices can contain any type, including other slices
package main
import "fmt"
func main(){
board := [][]string {
[]string{'_','_','_'}
[]string{'_','_','_'}
[]string{'_','_','_'}
}
board[0][0] = "X"
board[2][2] = "O"
board[1][2] = "X"
board[1][0] = "O"
board[0][2] = "X"
}
Appending a Slice
package main
import "fmt"
func main() {
var s[]int
fmt.Println(s)
//append works on nil slices, slice grows as needed
append(s,1)
fmt.Println(s)
//more than one element can be added
append(s,1,2,3,4)
fmt.Println(s)
}
Iterating through a slice (Range)
Iterating through a slice with the range
key word is possible. each range would return two elements. a key and a value so both of those should be captured.
package main
import "main"
func main(){
s[]int{1,2,3,4,5,6,7,8}
for i,v := range s {
fmt.Println(i,v)
}
}
Skipping Ranges
index of value in ranges can be skipped by using _ as a placeholder.
note: This is not possible for random variables like rust
package main
import "fmt"
func main(){
s[]{1,2,3,4,5,6,7}
for _,v := range s {
fmt.Println(v)
}
}
Maps
A map maps keys to values.
package main
import "fmt"
type Vertex struct{
Lat, Long float64
}
var m map[string]Vertex //type declaration for map
func main(){
m = make(map[string]Vertex)
m["A"] = Vertex{1.23412, 1.23456}
fmt.Println(m["A"])
}
Map Literals
Map literals are like struct literals but the keys are required
package main
import "fmt"
type Vertex struct{
lat, lang float64
}
var m map[string]Vertex {
"A": Vertex{1.234, 1.0987},
"B": Vertex{22.2342, 5.12321}
}
func main(){
fmt.Println(m)
}
The type inside the map can be ignored if it is a top-level type
type Vertex struc{
lat, long float64
}
var m map[string]Vertex{
"A": {1.22354, 5.623434 } //note the the 'vertex' Key word is not there
"B": {6.123412, 9.1232}
}
changing values in maps Mutating Maps
updating value in a map
m[key] = elem
retrieve a key
elem = m[key]
delete an element
delete(m,key)
Test that a key is present
elem, ok := m[key]
if ok is false i.e key not present then the elem is the zero value of the struct
Function Values
Functions are values too, they can be passed around just like other values.
package main
import "fmt"
func compute( fn func(float64 float64) float64 ) float64 {
return fn(3, 4)
}
func main(){
hypot := func(x,y float64) float64 {
return math.Sqrt(x*x + y*y)
}
fmt.Println(hypot(4,5)) //This is a function call using the variable that was assigned the function
fmt.Println(compute(hypot)) //sending the hypot function variable to compute, which is another function
}