Comment by netheril96
15 hours ago
I've swinged between Go and Rust for my personal projects multiple times. For work, it is decided by the management so not my problem.
The biggest gripe I have with Go is the lack of *any* compile time check for mutex. Even C++ has extensions like ABSL_GUARDED_BY. For a language so proud on concurrency, it is strange not to have any guardrails.
The guardrails are channels.
If you have a mutex on a structure, linters such as are packaged into Goland will catch oversights quite effectively.
If you are using fancier concurrency structures, you should consider channels instead.
Channels are not for everything. Plenty of mutex cases cannot be rewritten as channels, or will be very unwieldy so. In fact, every large Go project I have seen uses mutex here or there.
Theoretically you can use channels to simulate a mutex, but I agree with you there are use cases where a mutex makes more sense. They are even used in the standard library, for instance to implement sync.Once.
But generally I would agree that if you need to code parallel execution, channels are a good way to do it, because you can avoid race conditions if you share data only over channels. The biggest problem is that a lot of people don't understand, that channels with a buffer larger than 1 are a sign of problems in the architecture.
There is a type of parallel programming with workers for specific functions, that always leads to performance issues. The problem is you need to right-guess the distribution of work, when you have to define the amount of workers for a specific function. At least one go routine for one request is a much better approach than function-specific workers.