People talk about the lack of generics et al as being Go's downfall but personally what I've found to be the biggest annoyance is the very thing Go boasts to be good at: writing bug/race free multi-threaded code. Channels are vastly oversold given their actual suitability and worse still, add their own classes of race conditions (deadlocks) so you often fallback to using mutexes for those, hopefully rare, occasions y…
Generics could for instance have helped implement a mutex that disallows access to the memory that needs to be synchronized without locking it first. This of course wouldn't have helped here, as the root cause was holding on to the mutex for too long. I was under the impression that Go had first party tooling for deadlock checking, something called threadanalyzer if I recall correctly.
Did any language actually do that before rust?
It's also somewhat less useful without compiler-checked ownership as you can easily have the protected data escape the lock.