Fixed-lenght series of elements of a chosen type. The elements on a array ari initializod by default to the default value of that type.
var x [5]int
x[0] = 100
fmt.Println(x[4]) //0Array literals, is a predefined list of values that are used to initialize an array.
var x [5]int = [5]int{1,2,3,4,5}
var x [5]int = [...]int{1,2,3,4,5}//equivalentTo iterate through an array.
//i is the index,
//v is the value in a particular iteration,
//x is the array
for i, v := range x {
fmt.Printf("index %d, value %d", i, v)
}A slice is a dynamically-sized, flexible view into the elements of an array.
- Pointer: indicates the starte of the slice.
- Lenght: number of elements in the slice.
- Capacity: maximum number in the slice, from the start of the slice to the end ef the array.
array := [...]int{1,2,3,4,5}
slice := array[1:3] //slice of array
slice2 := []int{1,2,3,4,5} //slice literal - creates the underlying array, and the slice goes from its beginning to its endThe function make() creates a slice with a specified capacity. The 2 argument one is used to specify the type and capacity of the slice. The 3 argument one is used to specify the type, lenght and capacity of the slice.
slice2 := make([]int,10)
slice3 := make([]int,10,21)The function append() adds elements to the end of a slice, it creates a new underlying array if the capacity is not enough.
sli = append(sli, 777) //adds 777 to the end of the slicekey/value pairs data type.
| Key | value |
|---|---|
| Joe | x |
| Mary | y |
| John | z |
Is the implementation of the HashMap
The function make() can be used to create a map.
To access the value, the key is used.
To delete a key/value pair, the function delete() is used.
var idMap map[string]int //string is the typo of the key, and int is the type of the value
idMap = make(map[string]int)
idMap["Joe"] = 1 //adds a key/value pair, or changes the value if the key already exists
idMap:= map[string]int{ //map literal
"Joe": 1,
"Mary": 2,
"John": 3,
}
fmt.Println(idMap["Joe"]) //access the map //1
delete(idMap, "Joe") //deletes the key/value pair
id, p := idMap["Joe"] //checks if the key exists, and saves that to p as bool
len(idMap) //returns the number of key/value pairsTo iterate trough a map.
for k, v := range idMap {
fmt.Printf("key: %s, value: %d", k, v)
}Groups together other objects of different types
Example: Person Struct
Name, address, phone.
type Person struct {
name string
address string
phone string
}
var p1 Person
p1.name = "Joe"
p2 := new(Person) //creates a struct of type Person, initializes all its fiels to their zero value.
p3 := Person(name: "Joe",
address: "123 Main St",
phone: "555-555") //initializing witha a struct literalRequests for comments(RFC)
| Examples | |
|---|---|
| HTML | Hypertext Markup Language 1866 |
| URI | Uniform resource identifier 3986 |
| HTTP | Hypertext Transfer Protocol 2616 |
Protocol packages
- Go provides packages for the most important protocols.
- net/http > Web communication protocol
http.Get(www.google.com) - net > TCP/IP communication protocol
net.Dial("tcp", "uci.edu:80")
- net/http > Web communication protocol
- Function that encode and decode protocol format.
- JSON > RFC 7159 (attribute-value pairs)
{"name":"Mary","age":"19"}
- JSON > RFC 7159 (attribute-value pairs)
Properties
- All UNICODE
- Human readable
- Fairly compact representation
- Types can be combined recursively
- Array of structs
- Strinct of structs
Json Marshalling > Generating a JSON representation from an object.
Marshal() returns JSON rerpsentation as []byte
Unmarshal() returns an object from a JSON []byte representation.
p1:= Person(name: "Joe", address: "123 Main St", phone: "555-555")
var p2 Person
barr,err:=json.Marshal(p1)
err:= json.Unmarshal(barr, &p2)- Linear access, NOT random access
- Mechanical delay
- Basic operations
- Open - get handle for access
- Read - read bytes into []byte
- Write - write []byte into file
- Close - release handle
- Seek - move read/write head
Packages
- "io/ioutil" > basic functions
dat,e:= ioutil.ReadFile("file.txt") //dat is []byte with the contents of the entire file //opening and closing is not needed //large file may cause problems dat2 = "Hello World" ioutil.WriteFile("file.txt", dat2, 0777) //Arguments are: the name of file, the []byte to write, and the permissions
- "os" > Offers more control
os.Open() //opens a file //returns a file descriptor os.Close() //closes a file os.Read() //reads from a file into a []byte //the amount of bytes read, can be controlled by how big is the []byte passed as argument os.Write() //writes []byte into a file

Functions are set of instructions with a name. These provides a way to reuse code. Functions can hide details of implementation, and can be used to create abstractions. Funtions also help to improve understandability, specially when nome appropriately.
func main(){
findPupil()
}
func findPupil(){
grabImage()
filterImage()
findEllipses()
}Parameters are the input data needed to perform an operation. These are listen in parenthesis after the function name.
//declaration
func multiply(x int, y int /**parameters*/){
fmt.Println(x * y)
}
//call
multiply(2,3 /**argumments*/)Functions can return a value as a result of the operation. The return type is specified after the parenthesis of the function declaration.
func multiply(x int, y int) int /**return type is int*/{
return x * y
}
a := multiply(2,3)Functions in GO can have multiple return values.
func increase(x int) (int, int) /**return type is int*/{
return x , x + 1
}
a,b := increase(2)By Value
- Passed arguments are copied parameters
- Modifying parameters has no effect outside the function.
- Advantages
- data encapsulation
- Disadvatages
- To copy large data structures can be expensive By Reference
- Passing a pointer as argunment
- The function has direct acces to the variable in memory
- Advatages
- Faster, as it is not needed to create copies of variables
- Disadvantages
- No data encapsulation
//by value
func foo (y int){//takes an integer as argument
y = y + 1
}
func main(){
x := 1
foo(x)
fmt.Println(x)
}
//by reference
func foo (y *int){//takes a pointer of integer as argument
*y = *y + 1
}
func main(){
x := 1
foo(&x)
fmt.Println(x)
}Functions on GO are first-class.
- Functions can be treated as any other type.
- Variables con be of type function.
- Can be created dynamically
- Can be stored in a data structure
//declare variable of type function
var f func(int) int
//some other function
func addOne(x int) int{
return x + 1
}
func main(){
f = addOne //no parenthesis
fmt.Println(f(1))
}- Functions can be passed as arguments
func applyFunction(f func (int) int, x int) int{
return f(x)
}
func main(){
fmt.Println(applyFunction(addOne, 1))
}- Anonymous functions
v := applyIt(func (x int) int {return x+1}, 2)Functions can return functions. When functions are passe/returned, their environment comes with them.
Variable number of arguments, the arguments are treated as slice inside the function.
func getMax(values ...int)int{
max:=0
for _,v := range values{
if v > max{
max = v
}
}
return max
}
getMax(1,2,3,4,5,6,7,8,9,10)
//a slice can be passed, but ...needs fo follow the name of the slice.
slice:=[]int{1,2,3}
getMax(slice...)Function calls can be deferred until the sorrounding function completes. usally used for clean up activities.
func main (){
i:=1
defer fmt.Println(i+1)
i++
fmt.Print(i)
}- Classes are a collection of fields and functions that share a well defined resposability. Classes are a template, cotain data field, not actual data.
- Objects are instances of a class and contain actual data.
- Encapsulation makes so that the data can only be accesed by using method, in turn this makes it easy to guarantee data consistency.
Support for classes in GO
- There is no "class" keyword in GO.
- Method can have a receiver type,to indicate that they are associated with a Type.
- Dot notation can be used to call methods related with a type.
-
type MyInt int func (mi MyInt) double() int{ return int (mi*2) } func main(){ v:=MyInt(2) fmt.Println(v.double()) }
-
- Method associated with a type have an implicit first argument.
- Pointer receivers (to modify the object implicitly passed tho the function)
-
func (p *Point) Offset(v float64){ px = px + v }
-
No need to reference or dereference when using pointer receivers.
- Is the ability for an object to have diferent "forms" dependisc on the context
- Identical at a hing level of abstraction, and different at a low level of abstraction.
Interfaces
- Set of method signatures
- Name paramenters, return values.
- Implementation is not defined.
- Expresses a conceptual similarity between types.
Defining an iterface
type Shape interface{
Area() float64
Perimeter() float64
}
type Triangle {...}
func (t Triangle) Area() float64 {...}Disambiguate between types that implement the same interface.
func Draw2DShape(s Shape2D){
switch shape:=s.(type){
case Rectangle:
drawRect(shape)
case Triangle:
drawTriangle(shape)
}
}Many go programs return error interface
type error interface{ Error() string }If there is no error then "error==nil" otherwise, error would indicate the actual error.
Parallel execution is not the same as concurrency
- Happens when two programs execute in at exactly the same time. 1 core of the cpu runs 1 instruction at a time.
- Tasks may complete more quickly.
- Not all tasks are parallelizable.
Moore's Law - Prodictod transistor densitiy would double every two years. (not an actual law, just an observation)
- Happens when two programs execute in overlapping time periods, but these are not executing at the same time.

- Concurrent tasks may be executed on the same hardware.
- In GO mapping from tasks to hardware is not directly controlled by the programmer.

- Hiding Latency
- A process is an instance of a program that is being executed.
- A process may have
- Memory
- Virtual address space
- Code, stack, heap, shared libraries, etc...
- Registers
- Program counter
- Data Regs
- Stack pointer
- Memory
Operating Systems
- Allow many processes to execute concurrently.
- Provide fair access to resorces
- Scheduling
- Gives the illusion of parallel execution.
- Goroutines
- Interleavings
- Order of execution within a task is known, but the order of execution between concurrent tasks is not known.
- Interleaving of instructions between tasks is unknown.
- Many interleavings are possible.
- Programmer must consider all possibilities.
- Ordering is non-deterministic.
- Race conditions
- Outcome depends on non-deterministic ordering.
- Races occur due to communication.
- Threads are not completele independent
- Creating goroutines
- One goroutine is created automatically to execute the
main()function. - Other goroutines con be created using the
gokeyword.func main(){ a:=1 go foo() fmt.Println("World") }
- One goroutine is created automatically to execute the
- Exiting goroutines
Adding a delay to wait for a goroutine is bad! Time asumptions may be completely wrong.
Using global events whose execution is viewed by all threads, symultaneously.

Sync WaitGroup
sync.WaitGroupis a synchronization primitive, that forces a goroutine to wait for other goroutines to complete.- Contiains an internal counter. the counter is decreased each time a goroutien completes.

Goroutine communication
- Goroutines usually work together to perform a bigger task. Channels
- Transfer data botwees goroutines.
- Chanels are typed, and can only transfer data of that type.
make()is used to create a channel.-
ch:=make(chan int)
-
- Are used to recive and send data.
-
ch<-1 //send data on channel x:=<-ch //recive data from channel
-
Example
func prod(v1 int, v2 int, c chan int){
c<-v1*v2
}
func main(){
c:=make(chan int)
go prod(1,2,c)
go prod(3,4,c)
a:=<-c
b:=<-c
fmt.Println(a*b)
}- Channels can contain a limited number of objects. By default is 0 (unbuffered).
- Optional argument in
make() 
- Buffer will not block, unless is full.

- It is commen to iteratively read from a channel; one iteration each time a new value is received.
for v:=range ch{ fmt.Println(v) }
- The cycle will continue until close is called on the channel.
close(ch) - Data may also be received from multiple channels.
Choice on which data to use, when multiple channels are available.
- First-come-first-served
- Waits on the first data from a set of channels.
-
select{ case v:=<-ch1: fmt.Println(v) case v:=<-ch2: fmt.Println(v) }
- Select may be used to select either send or receive operations.
-
select{ case a = <- inchan: fmt.Println("Roceived a") case b <- inchan: fmt.Println("Sent b") }
- Select with an abort channel
-
for{ select{ case v:=<-ch1: fmt.Println(v) case <-abort: //abort is a different channel, and as soon a it gots some data, the for loop will stop. return } }
- If the
selectstatement contains a default case, it will not block, if non of the other cases are ready.
Sharing variables concurrently may cause problems, If two or more goroutines are writing to a shared variable, they may interfere with each other.
A function can be "Concurrency-Safe" when a function can be invoked without interfering with other goroutines.
DO NOT let 2 goroutines write a shared variable at the same time.
Writing to shared variables should be mutually exclusive. That means that some code segmentes en different goroutiens should not execute concurrently

- Methods
Lock()sets the flag up- The shared variable is in use.
- If the variable is locked by a goroutine, other goroutines cannot use that shared varible, until the lock goes down.
Unlock()sets the flag down- The shared variable is not in use.
- Other goroutines can use the shared variable.
-
var i int = 0 var mut sync.Mutex func inc(){ mut.Lock() i++ mut.Unlock() }
Syncronous Inizialization
- Must only happen once
- Must happen before everything else
- Package Sync.Once
- Has one method,
once.Do(f) - The function
fis executed only one time, even if it is called on multiple goroutines. - All calls to
once.Do(f)will block until the first returns. That way initialization is is ensured. -
var wg sync.WaitGroup var on sync.Once func main(){ wg.Add(2) go doStuff() go doStuff() wg.Wait() } func doStuff(){ on.Do(setup) fmt.Println("Doing stuff") wg.Done() } func setup(){ fmt.Println("Init") }

- Has one method,
Cicular dependencies cause all involved goroutines to block.
G1 waits for G2, and G2 is also waiting for G1.









