In some scenarios, calculating the hash of a piece of data is useful, for instance when you only need to know that something in the dataset has changed, no matter what. Calculating a hash is moderately computing consuming but has some advantadges: Avoids checking the changes field by field of the dataset Allows storing only the data hash instead of the whole dataset In Golang, calculating MD5 hashes of structs can be achieved by using a code piece as this: import ( "bytes" "crypto/md5" "encoding/gob" "encoding/hex" "fmt" ) // Random struct, just for demo purposes type MySubStruct struct { Zaz *bool } type MyStruct struct { Foo int Bar []string Baz MySubStruct } func main() { // Hasheable struct myBool := false myStruct := MyStruct{ Foo: 67372388, Bar: []string{"b", "ar", ""}, Baz: MySubStruct{ Zaz: &myBool, }, } // Crea...
This is the second article of a series analyzing Go concurrency, ie, parallel execution of different threads using Go. The series is composed of these articles: The Go concurrency foundation: goroutines . This one, in which synchronization between subprocesses, specifically by using Go waitgroups , is analyzed. Data exchange between subprocesses: Go channels Why synchronization between subprocesses The first article of the series exposed an example that clearly demonstrated why the subprocess synchronization is needed specifically in go: package main import ( "fmt" "time" ) // mySubprocess sleeps for a second func mySubprocess() { fmt.Println("Entering to mySubprocess") time.Sleep(1 * time.Second) fmt.Println("Exiting from mySubprocess") } // main program process func main() { fmt.Println("Calling mySubprocess from main()...") go mySubprocess() fmt.Println("mySubprocess finished!...