Posts

Showing posts from December, 2022

51. Go - Error Handling

Error Handling is used with functions that returns an err. Uses second variable comma declarations. Example: print , err := fmt. Println ( "HELLO" )     if err != nil {         fmt. Println ( "ERROR" )     } Ways to Print Errors:     fmt. Println (wgs, "FINISHED" )     print , err := fmt. Println ( "HELLO" )     if err != nil {         fmt. Println ( "ERROR" )         log. Println ( "ERROR" )         log. Fatal ()         log. Fatalf ( "ERROR" )         log. Fatalln ( "ERROR" )         log. Panic ()         log. Panicf ( "ERROR" )         log. Panicln ( "ERROR" )     } // Fatal exists program.. // Panic is mid serious, does not exit program and have ability to recover. // Log gives ability to log the error into a file. // fmt.print, prints error to standard output. Logging // prints or outputs into a designated file. package main import (     "fmt"     "log"  

50. Go - Channel Fan In / Fan Out

Fan In is taking all values from different channels and funnel them into one channel for easier processing. Example: // Note: these channels are taking and pulling one value at a time. package main import (     "fmt"     "sync" ) func main () {     // Two Channels     channel1 := make ( chan int )     channel2 := make ( chan int )     // Funnel Channel     channel3 := make ( chan int )     // Add values into Channel 1  then close     go func () {         for i := 0 ; i < 100 ; i += 2 {             channel1 <- i         }         close (channel1)     }()     // Add values into Channel 2 then close     go func () {         for i := 0 ; i < 100 ; i += 3 {             channel2 <- i         }         close (channel2)     }()     // Pull values from both channels and funnel into channel 3 until both channels are closed.     go func (chan1, chan2 <- chan int , chan3 chan <- int ) {         var wg sync.WaitGroup         wg. Add ( 2 )  

49. Go - Channels with Comma,OK Statements

Comma Ok statements is useful to check whether the channel is closed. They also block if channel hasn't gotten any values yet. Example: package main import (     "fmt"     "time" ) func main () {     ch1 := make ( chan string )     go func () {         time. Sleep (time.Second * 10 )         ch1 <- "string"     }()     v , ok := <-ch1     fmt. Println (v, ok) } Example: package main import (     "fmt"     "time" ) func main () {     ch1 := make ( chan string )     go func () {         time. Sleep (time.Second * 5 )         ch1 <- "string"     }()     // Channel is open     v , open := <-ch1     fmt. Println (v, open)     close (ch1)     // Channel is closed     v , open = <-ch1     fmt. Println (v, open) }

48. Go - Select Statements

Select statements are like switch statements. The difference is that select statements are used when there are goroutines and channels. Select statement will execute a case based on whether the case channel is "READY", meaning it has a value in the channel ready to use. If all the cases have a value, then the select statement will randomly choose a case. If no values are ready and select statement is called, then default case will be chosen. Example: package main import (     "fmt"     "time" ) func addTen (channel, channel2 chan int ) {     for i := 0 ; i < 10 ; i++ {         time. Sleep (time.Second * 1 )         channel <- i     } } func addTen2 (channel chan int ) {     for i := 10 ; i < 20 ; i++ {         time. Sleep (time.Second * 5 )         channel <- i     } } func main () {     ch1 := make ( chan int )     ch2 := make ( chan int )     ch3 := make ( chan int )     go addTen (ch1, ch3)     go addTen2 (ch2)     go fun

47. Go - Channel Ranges

Can iterate over channel values from buffer list. close() // Closes the channel so channel does not expect any more values. still can read, but not receive. // Should close a channel before ranging over it to avoid deadlock error. Example: package main import "fmt" func main () {     channelOne := make ( chan int )     go func () {         for i := 0 ; i < 50 ; i++ {             channelOne <- i         }         close (channelOne)     }()     for i := range channelOne {         fmt. Println (i)     } } // using for range to iterate over a channel until it is closed. // it keeps pulling values from the channel until the channel is closed, then range loop ends. // channel is finally closed in the goroutine func after the 50 loop.

46 . Go - Channels - Directional

Making Directional Channels (Only Send OR Receive) channel := make(chan string) channel := make(<-chan string) // receive only, only can receive stuff from channel channel := make(chan<- string) // send only, only can put stuff in channel // Useful when declaring directional in functions. Example: package main import "fmt" func addTo (c chan <- string ) {     c <- "MESSAGE"     fmt. Println ( "MESSAGE SENT" ) } func takeFrom (c <- chan string ) {     fmt. Println ( "RECEIVED: " , <-c) } func main () {     channelOne := make ( chan string )     go addTo (channelOne)     takeFrom (channelOne) // only runs after something is in channel because channel block }

45. Go - Atomic Write/Load Int64

Atomic lets write and load int64 without race conditions. Alternative to Mutex or if want to just increment ints. package main import (     "fmt"     "sync"     "sync/atomic" ) func main () {     var counter int64     var wg sync.WaitGroup     wg. Add ( 100 )     for i := 0 ; i < 100 ; i++ {         go func () {             atomic. AddInt64 (&counter, 1 )             wg. Done ()         }()         //fmt.Println(counter)         fmt.Println(atomic. LoadInt64 (&counter))     }     wg. Wait ()     fmt. Println (counter) } // atomic.AddInt64(ADDRESS,INCREMENT) increments/write to a variable safely // atomic.LoadInt64(ADDRESS) loads/reads a variable

44. Go - Goroutine Race Conditions & Mutex

Race Condition Example: package main import "fmt" func main () {     counter := 0     for i := 0 ; i < 100 ; i++ {         go func () {             temp := counter             temp++             counter = temp         }()     }     fmt. Println (counter) } The counter never reaches 100 (100 goroutines counting suppose to increment count by 1) because each goroutine access the counter value at different point in time and then resets the counter where other goroutines will access later. package main import (     "fmt"     "time" ) func main () {     counter := 0     for i := 0 ; i < 101 ; i++ {         go func () {             temp := counter             temp++             counter = temp         }()         fmt. Println (counter)         time. Sleep (time.Millisecond * 50 )     }     fmt. Println (counter) } Adding Sleep Helps. package main import (     "fmt"     "sync" ) func main () {     counter := 0     var

43. Go - Sorts and Custom Sorts

Go built in sort functions can sort default slice variables and also custom ones. Example: Ints and Strings package main import (     "fmt"     "sort" ) func main () {     numbers := [] int { 5 , 2 , 8 , 2 , 52 , 111 }     words := [] string { "hello" , "die" , "pink" , "ablw" }     fmt. Println (numbers)     fmt. Println (words)     sort. Ints (numbers)     sort. Strings (words)     fmt. Println (numbers)     fmt. Println (words) } Custom Sort: requires giving the type of data we want to sort a list of similar methods of the built in sort functions so they can be of the same interface. https://pkg.go.dev/sort#example-package Using sort.Sort(Custom(struct)) Example: package main import (     "fmt"     "sort" ) type blob struct {     Size int     Name string } type bySize []blob type byName []blob func (a bySize) Len () int           { return len (a) } func (a bySize) Swap (i, j int )      

42. Go - JSON

Marshalling (Turning struct types into JSON format: Code Example: // marshall function takes anything and returns a slice of bytes package main import (     "encoding/json"     "fmt"     "os" ) type serverInfo struct {     ID       int     Name     string     IsNew   bool     Members [] string } func main () {     serverOne := serverInfo{         ID:       0 ,         Name:     "Crimson" ,         IsNew:   false ,         Members: [] string { "Bob" , "Ada" },     }     marshall , err := json. Marshal (serverOne)     if err != nil {         fmt. Println (err)     }     fmt. Println (marshall) // not correct format print     os.Stdout. Write (marshall) // write output } Un-Marshalling (Decoding a JSON format, which is a array of bytes for GO. // unmarshall function takes a slice of byte and interface and returns an error. Takes decoded JSON and stores it at address given by interface. Code Example: package main import

41. Go - Closure

Code blocking code to limit scope. Code blocking with curly brackets. Example: package main import "fmt" func main () {     x := 5     fmt. Println (x)     {         y := 10         fmt. Println (y)     } } Example 2: package main import "fmt" func plus () func () int {     var x int     return func () int {         x++         return x     } } func main () {     test := plus ()     test2 := plus ()     fmt. Println ( test ())     fmt. Println ( test ())     fmt. Println ( test2 ())     fmt. Println ( test2 ()) } Return Function with inner closure scope: package main import "fmt" func printerr () func () int {     x := 0     return func () int {         x++         return x     } } func main () {     test1 := printerr ()     fmt. Println ( test1 ())     test2 := printerr ()     fmt. Println ( test2 ())     fmt. Println ( "TWO" )     fmt. Println ( test2 ())     fmt. Println ( test2 ())     fmt. Println ( test2 ())    

40. Go - Callbacks

Callbacks are passing a func as an argument in a func. package main import "fmt" func sumTotal (l [] int ) int {     total := 0     for _ , e := range l {         total += e     }     return total } func oddOnly (f func (l [] int ) int , l [] int ) int {     oddList := [] int {}     for _ , e := range l {         if (e % 2 ) != 0 {             oddList = append (oddList, e)         }     }     return f (oddList) } func main () {     numList := [] int { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 }     fmt. Println ( oddOnly (sumTotal, numList)) }

39. Go - Defer

Defer is used to delay function execution to initialize after the surrounding statements/functions below are returned. Since defer will always get executed when the surrounding function returns, it is a good place to attach cleanup code such as: Closing open files Releasing network resources Closing the Go channel Committing database transactions And so on Example: package main import "fmt" func main () {     defer fmt. Println ( "Hello Word" )     fmt. Println ( "Introduction to defer statement in Go" ) }

38. Go - Functions

Function format: func (receiver) identifier(arguments) (returns) {CODE} // can receive more than one argument by using variadic parameter (...), also applies to returns Example: // pointer used on personB to change the todd variable's values in main func. package main import "fmt" type personB struct {     name string     age   int } func (p *personB) rename (n string ) string {     p.name = n     return p.name } func main () {     todd := personB{         name: "todd" ,         age:   10 ,     }     fmt. Println (todd.name)     fmt. Println (todd. rename ( "bobby" ))     fmt. Println (todd.name) } Anonymous Functions: // Format: func(parameters) {CODE} (parameters input) // Use inside functions. Code will autorun     func (x int ) {         fmt. Println (x)     }( 50 ) Func Expressions (variables as a func): package main import "fmt" func main () {     test := func () {         fmt. Println ( "HETS" )     }     test

37. Go - Multi-dimensional Slices

A table that holds another table is multi-dimensional. package main import "fmt" func main () {     num := [] int { 1 , 2 }     nump := [] int { 3 , 4 }     x := [][] int {num, nump}     fmt. Println (x) }

36. Go - Interface{}

interface{} is a type that holds any type package main import (     "fmt" ) func main () {     variadicExample ( 1 , "red" , true , 10.5 , [] string { "foo" , "bar" , "baz" },         map [ string ] int { "apple" : 23 , "tomato" : 13 }) } func variadicExample (i ... interface {}) {     for _ , v := range i {         fmt. Println (v)     } } // "...interface{}" used here is used to make a table of any type given. Example: package main import "fmt" func main () {     folder := [] interface {}{}     folder = append (folder, 5 )     folder = append (folder, "string" )     folder = append (folder, 124.14 )     for _ , e := range folder {         fmt. Println (e)     } }

35. Go - Variadic

Variadic functions can accept any number of inputs. Example: // variadic parameter must be only argument or the last argument. // takes in 0 or more values package main import "fmt" func main () {     printEverything ( "hello" , "hello" , "hello" , "hello" , "hello" , "hello" , "hello" ) } func printEverything (s ... string ) {     if len (s) != 0 {         for i := 0 ; i < len (s); i++ {             fmt. Println (s[i])         }         fmt. Println ( "Length:" , len (s))     } } Using variadic to get all values from a slice: // "y..." means pull all value from y slice package main import "fmt" func main () {     x := [] int { 1 , 2 , 3 }     y := [] int { 4 , 5 , 6 }     x = append (x, y...)     fmt. Println (x) } Using variadic of interface to get any type of value: package main import (     "fmt" ) func main () {     variadicExample ( 1 , "

34. Go - Continue

Continue statement allows continuing of the loop but voiding everything below it.  package main import "fmt" func main () {     for i := 0 ; i < 10 ; i++ {         if i% 2 == 0 {             fmt. Println ( "EVEN" , i)             continue         }         fmt. Println ( "ODD" , i)     } }

33. Go - Bitshifting

Operator: << or >> Used to shift binary numbers left or right. Or times 2 vs divide by 2. n << 5 , n times 2 five times n >> 5 , n divided 2 five times.

32. Go - Ioat

Iota is used with const to make variables increment by 1. Example: const ( a = ioat b c ) "a" will print 0 "b" will print 1 "c" will print 2 Could use iota in expressions: a := iota * 5