example<\/a>.<\/li>\n<\/ul>\nimport "sync"\n\nfunc doSomething(wg *sync.WaitGroup) { \/\/<-- Note we are passing a pointer!\n...\n\twg.Done() \/\/ signal this worker is done\n}\n\nvar wg sync.WaitGroup\nwg.Add(2) \/\/ indicate we will wait for 2 workers\ngo doSomething(&wg)\ngo doSomething(&wg)\n\nwg.Wait() \/\/ wait until all workers have .Done()\n\/\/NOTE: You pass the wait group by reference (i.e. pointer) or each\n\/\/ goroutine will get a copy of its own WaitGroup!\n<\/code><\/pre>\nSelect<\/h3>\n\nAllows you to block and wait for any number of channel send or receive operations. When multiple channels are ready, then a random case will be chosen to process.<\/li>\n<\/ul>\nch1 := make(chan string)\nch2 := make(chan string)\ngo processSomething(ch1)\ngo processSomething(ch2)\n\nselect {\ncase val1 := <- ch1:\n\t\/\/ received from channel 1\ncase val2 := <- ch2:\n\t\/\/ received from channel 2\n}\n<\/code><\/pre>\n\nYou can also add a default<\/code> case that will be called when no other case is ready and thus the select can be non-blocking.<\/li>\n<\/ul>\nMutex<\/h3>\n\nCritical section recap. A critical section is a section of code that must be guaranteed to only be executing on a single thread (e.g. incrementing a counter) at a time and thus prevent a race condition.<\/li>\n Use a mutex to protect a critical section and thus only one goroutine can execute the critical section code.<\/li>\n<\/ul>\nimport "sync"\n\nvar mutex sync.Mutex\nmutex.Lock()\n... \/\/ critical section\nmutex.Unlock()\n<\/code><\/pre>\nNew<\/h3>\n\nGo is not OOP in the \u201ctraditional\u201d sense. You don\u2019t have classes and you don\u2019t have constructors.<\/li>\n How do you prevent an instance of a struct to be made where the zero value is not valid. Meaning this is where constructors in other languages come in.<\/li>\n You un-export (e.g. make \u201cprivate\u201d) the type by using camelCase (lowercase initial letter).<\/li>\n You declare an exported function named NewT<\/code> where T is the name of the type you are constructing and returning. Seems to be convention that if only one type is exported from the package then you simply use New<\/code>.<\/li>\n<\/ul>\npackage person\n\ntype person struct { \/\/<- note the lowercase initial\n...\n}\n\nfunc New(params) person {\n... \/\/ construct and return a valid person\n}\n\n\/\/ ... some other package\np1 := person.New()\n<\/code><\/pre>\nDefer<\/h3>\n\nUse defer<\/code> to execute a function\/method call just before the containing function exits.<\/li>\nArguments passed to the deferred function will be the value at the time the defer call is \u201cscheduled\u201d and not when the deferred function is actually being executed.<\/li>\n<\/ul>\na := 42\ndefer callMeAtTheEnd(a)\na = -200\n\/\/ here the containing function is finished and thus\n\/\/ code execution will look something like this\n\/\/ callMeAtTheEnd(42)\n<\/code><\/pre>\n\nMultiple defer call can be \u201cscheduled\u201d and a stack is used where the deferred calls are made in LIFO (Last In First Out) order.<\/li>\n<\/ul>\ndefer one()\ndefer two()\ndefer three()\n\/\/ The order of calls will be\n\/\/ three(), two(), one()\n<\/code><\/pre>\nError handling<\/h3>\n\nErrors are just values. They implement the error<\/code> interface.<\/li>\nGo doesn\u2019t have \u201craise exception\u201d or \u201ctry catch\u201d handling.<\/li>\n When an error is returned from a function, then it is convention to have it as the last type.<\/li>\n<\/ul>\nfunc Open(name string) (file *File, err error)\n\nf, err := Open("\/something")\nif err != nil {\n...\n}\n<\/code><\/pre>\n\nIdiomatic Go is to check the error against nil<\/code>.<\/li>\nThe error<\/code> interface looks like this:<\/li>\n<\/ul>\ntype error interface { \n Error() string\n}\n<\/code><\/pre>\n\nWhich means that any type that implements Error() string<\/code> method can be used as an error<\/code>.<\/li>\nEasy to way to create \u201csimple\u201d errors.<\/li>\n<\/ul>\nimport "errors"\n\nerr := errors.New("My shiny new error that is just a string")\n\n\/\/ What if I want a formatted string error?\nimport "fmt"\n\nerr := fmt.Errorf("Ouch the server returned %d status code", status)\n<\/code><\/pre>\nFirst class functions<\/h3>\n\nRecap: A first class type means that it can be assigned to variables, passed to functions as arguments and be returned from functions.<\/li>\n In Go functions are first class (meaning can be assigned to a variable, passed to functions and returned from functions).<\/li>\n Anonymous function.<\/li>\n<\/ul>\ncallMe := func() {\n... \/\/ do something\n}\n\n...\ncallMe()\n\n\/\/ Or to declare and call without assigning to a variable\nfunc() {\n...\n}() \/\/ <- note the () to execute the function\n\n\/\/ Yes you can have arguments\nfunc(name string) {\n...\n}("Jannie")\n<\/code><\/pre>\n\nHow do you do \u201ctypealiasing\u201d like I would in Swift to give a closure a type?<\/li>\n<\/ul>\ntype Handler func(who string, what string) int\n\nvar handler Handler = func(who string, what string) int {\n...\n}\n\nresult := handler("jannie", "did something")\n<\/code><\/pre>\n\nHigher-order function: A function that takes one or more functions as arguments and that returns a function.<\/li>\n Closures: Functions that capture values from the outside scope.<\/li>\n<\/ul>\na := 42\nfunc() {\n\tfmt.Println("I am a closure that closes over a = ", a)\n}\n<\/code><\/pre>\n<\/div>\n","protected":false},"excerpt":{"rendered":"Featured image by\u00a0Egon Elbre […]<\/p>\n
Read more →<\/a><\/p>\n","protected":false},"author":2,"featured_media":552,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[52],"tags":[53],"yoast_head":"\nLearning Go - Day 4 - Andr\u00e9 Jacobs<\/title>\n \n \n \n \n \n \n \n \n \n \n \n\t \n\t \n\t \n \n \n \n \n \n\t \n\t \n\t \n