Strongly disagree. Yes, it is not a free lunch but they have made several deliberate decisions. If you code your Go like you would C++, you are not using the language in its intended fashion.
They have nice features like a data race detector and deadlock detector.
Channels are not just a concurrent queue, they have nice deliberate things built into them. They are based off of Communicating Sequential Processes (CSP), which has influenced other languages like Rust and Erlang as well.
Green threads are very cheap, and therefore remove yet another thing to think about when using threading. They have made good decisions around the memory model for them as well.
When I worked in C, the first thing we’d do in a new program is introduce a green thread-like scheduler so we could achieve concurrency. Then achieving parallelism is as simple, heh, as bumping up the number of worker threads and fixing the data races. Go handles both of this for you from the start.
So sure, when you are aware of sound multi threading design, know what TSAN is, and have a lot of experience with C++ you can look at Go and scoff and say Rust is better.
But for 90% of the programmers I meet in my career, especially those who grew up in the age of the internet, they do not have experience with this and greatly benefit from Go.
I am in probably one of HN’s “most coveted” engineering companies, and barely anyone has worked in largely multithreaded programs. It is such a problem that we are now splitting services into processes to avoid handling multithreading.
But over in our Go-world this is just not a concern. Seriously, Go is designed really well for backend services. I used to hate on it a lot, but after working at larger tech companies I have bought into it more for those use-cases.